2011-09-20 44 views
4

我有一个修改后的T4模板,它可以从我的edmx构建类,除了派生类外,它的工作流畅。如何在声明中有条件地设置基类

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

TranslatedProduct : Product : BaseItem // dang 

我很困惑如何以及在哪里可以有条件地设置T4模板忽视:BaseItem在派生类中的情况下 - 即

TranslatedProduct : Product 

例如:

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

在我的脑海中,我想像它 -

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))#> 
} 

但我收到语法错误,所以我想看看是否有其他人试过这个,如果我在正确的道路上

回答

11

您提供硬编码: BaseItem始终显示的脚本。这似乎打破了。

原始代码是:

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

这将使用定义的类:

C:\ Program Files文件(x86)的\微软的Visual Studio 10.0 \ Common7 \ IDE \扩展\微软\实体框架工具\模板\包括\ EF.Utility.CS.ttinclude

<#= #>标签之间的脚本的部分仅仅是C#表达式和日由这些表达式返回的字符串被内联插入。

code.Escape方法将返回类型名称(作为字符串)或空字符串。

code.StringBefore将在第二个字符串(基本类型名称)之前追加第一个字符串(" : "),但仅当第二个字符串不为空或空时追加。

要做你想要完成的事情,你可以使用他们使用的相同技巧,但相反。不幸的是,你不能使用他们现有的课程,因为他们没有某种AppendIfNotDefined方法。所以我们只会使用更复杂的表达式。

相反的:

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

我们会写:

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

这里是整条生产线,全部挤在一起:

<#=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))#> 
+0

感谢您的答复 - 这很好,但什么我以后是默认行为。即。使所有类继承BaseItem,除非它是派生类。这行代码是T4的默认行为。 – MikeW

+0

让我进一步澄清 - 这个默认的BaseClass不是模型的一部分 - 因为它看起来与T4生成的类非常不同。因此,虽然可能不是最好的解决方案,但它是一个简单的解决方法 – MikeW

+0

@MikeW:因此,位于'<#= #>'标记之间的T4模板部件是简单的C#表达式。你知道什么'entity.BaseType'评估为顶级类型?例如,它是否为空? –