Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally set base class in declaration

I have a modified T4 template that builds classes from my edmx and its working smoothly except for derived classes.

Product : BaseItem // works fine as do all top level classes

TranslatedProduct : Product : BaseItem  // dang

I'm confused about how and where I can conditionally set the T4 template to ignore : BaseItem in the case of a derived class - ie

TranslatedProduct : Product

For example:

<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#> : BaseItem

In my head i imagined it like -

if(code.Escape(entity.BaseType).Equals(string.empty)
{
   <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> : BaseItem
}
else
{
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial      class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
}

But I receive syntax errors so I'd like to see if anyone else has tried this and if I'm on the right path

like image 999
MikeW Avatar asked Dec 22 '22 08:12

MikeW


1 Answers

The scripts you provided hard-code : BaseItem to always appear. This seems broken.

The original code is:

<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>

This uses a class defined in:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude

The portions of the script between <#= #> tags are just C# expressions, and the strings returned by those expressions are inserted inline.

The code.Escape method will return either the type name (as a string) or an empty string.

The code.StringBefore will append the first string (" : ") before the second string (the base type name), but only if the second string isn't null or empty.

To do what you're trying to accomplish, you can use the same trick they use, but in reverse. Unfortunately you can't use their existing class, because they don't have some sort of AppendIfNotDefined method. So we'll just use a more complicated expression.

Instead of:

code.StringBefore(" : ", code.Escape(entity.BaseType))

We'll write:

code.StringBefore(" : ",
    string.IsNullOrEmpty(code.Escape(entity.BaseType))
        ? "BaseItem"
        : code.Escape(entity.BaseType)
    )

Here's the whole line, all crammed together:

<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", string.IsNullOrEmpty(code.Escape(entity.BaseType)) ? "BaseItem" : code.Escape(entity.BaseType))#>
like image 63
Merlyn Morgan-Graham Avatar answered Dec 24 '22 02:12

Merlyn Morgan-Graham