ADO.NET EntityObject 生成器模板

本主题概述了随 Visual Studio 2010 提供的**“ADO.NET EntityObject 生成器”**模板,还演示了如何自定义文本模板。 **“ADO.NET EntityObject 生成器”**模板生成类型化 ObjectContext 和从 EntityObject 派生的实体类(对象层代码)。

**“ADO.NET EntityObject 生成器”**模板生成的代码与实体设计器生成的默认代码相同。 ADO.NET EntityObject 生成器模板由一个文本模板文件组成:<模型名称>.tt。 <模型名称>.tt 模板输出一个源文件 <模型名称>.cs(或.vb),该源文件出现在解决方案资源管理器中的 <模型名称>.tt 的下面。

<模型名称>.tt 文件代码概述

首先,代码使用内置指令指示文本模板处理引擎如何处理模板。 文本模板包括 .ttinclude 文件,此文件包含可有助于代码生成过程的实用工具类。 有关 .ttinclude 文件的更多信息,请参见实体框架实用工具 .ttinclude 文件

<#@ template language="VB" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.VB.ttinclude"#>
<#@ output extension = ".vb" #>
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ output extension=".cs"#>

然后,它创建一个 UserSettings 类型的实例,此实例允许用户指定应如何写出代码。 例如,此类型确定是否将 Camel 大小写格式用于字段名称,或确定是否将 AddTo 方法添加到生成代码的类型化对象上下文类中。

<#
    Dim userSettings As UserSettings =
        New UserSettings With _
        { _
            .SourceCsdlPath = "SchoolModel.edmx", _
            .ReferenceCsdlPaths = new string () {}, _
            .FullyQualifySystemTypes = True, _
            .CreateContextAddToMethods = True, _
            .CamelCaseFields = False _
        }

ApplyUserSettings(userSettings)
#>
<#
UserSettings userSettings =
        new UserSettings
        {
            SourceCsdlPath = @"SchoolModel.edmx",
            ReferenceCsdlPaths = new string[] {},
            FullyQualifySystemTypes = true,
            CreateContextAddToMethods = true,
            CamelCaseFields = false,
        };

ApplyUserSettings(userSettings);
#>

然后,代码将 .ttinclude 文件中定义的 Helper 类进行实例化和初始化。 还将初始化一些局部变量。

<#
Dim loader As New MetadataLoader(Me)
Dim ef As New MetadataTools(Me)
Dim region As New CodeRegion(Me)
Dim code As New CodeGenerationTools(Me) With {.FullyQualifySystemTypes = userSettings.FullyQualifySystemTypes, .CamelCaseFields = userSettings.CamelCaseFields}

ItemCollection = loader.CreateEdmItemCollection(SourceCsdlPath, ReferenceCsdlPaths.ToArray())
ModelNamespace = loader.GetModelNamespace(SourceCsdlPath)
Dim namespaceName As String = code.VsNamespaceSuggestion()
UpdateObjectNamespaceMap(namespaceName)
#>
<#
MetadataLoader loader = new MetadataLoader(this);
MetadataTools ef = new MetadataTools(this);
CodeRegion region = new CodeRegion(this);
CodeGenerationTools code = new CodeGenerationTools(this){FullyQualifySystemTypes = userSettings.FullyQualifySystemTypes, CamelCaseFields = userSettings.CamelCaseFields};

ItemCollection = loader.CreateEdmItemCollection(SourceCsdlPath, ReferenceCsdlPaths.ToArray());
ModelNamespace = loader.GetModelNamespace(SourceCsdlPath);
string namespaceName = code.VsNamespaceSuggestion();
UpdateObjectNamespaceMap(namespaceName);
#>

初始化之后,将混合文本块和代码块用于生成输出文件的文本。 foreach(在 Visual Basic 中为 For Each)循环用于基于 GetSourceSchemaTypes Helper 函数返回的元数据信息写出文本。 GetSourceSchemaTypes Helper 函数在 <模型名称>.tt 文件中进行定义并调用 GetItems 方法来从项集合中获取所有指定类型的项。 以下是写出到 <模型名称>.cs 或 <模型名称>.vb 文件的代码的说明:

  1. EDM 关系元数据。

  2. 类型化 ObjectContext 的定义。 类定义包括:构造函数重载、ObjectSet 属性、AddTo 方法(如果将 UserSettings.CreateContextAddToMethods 设置为 true)和函数导入方法(如果在概念模型中定义任何此类方法)。

    <模型名称>.tt 文件中的以下代码写出类型化 ObjectContext 类。

    <#=Accessibility.ForType(container)#> Partial Class <#=code.Escape(container)#>
        Inherits ObjectContext
    
    <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : ObjectContext
    

    如果容器名称为 SchoolEntities,则在 <模型名称>.cs 或 <模型名称>.vb 文件中生成以下代码:

    Public Partial Class SchoolEntities
        Inherits ObjectContext
    
    public partial class SchoolEntities : ObjectContext
    
  3. 实体类型类。 这些类派生自 EntityObject,并包括定义如何将对象层中的实体类型映射到概念模型中的实体类型的特性。 实体类的定义包括工厂方法以及基元属性、复杂属性和导航属性。

  4. 复杂类型类。 这些类派生自 ComplexObject,并包括定义如何将对象层中的复杂类型映射到概念模型中的复杂类型的特性。

然后,定义 Helper 函数。 在文本模板中,Helper 函数包含在类功能块中。 您可以通过使用 <#+#> 来指示类功能标记。

自定义对象层代码

如果您想要自定义生成对象层代码的方式,则必须修改 .tt 文件。 您可能需要修改类型化对象上下文的名称;为实体类型添加新的或者修改现有的属性或特性;或者让实体类型从某个接口继承。 若要自定义对象层代码,可以修改 .tt 文件中的文本块(此文本块位于 <##> 标记的外部)。

若要更改类型化对象上下文的名称,请在所有 <#=code.Escape(container)#> 的前面添加相应的单词(例如,My)。 然后,如果容器在 .edmx 文件中的名称为 SchoolEntities,则容器在生成的代码中的名称将为 MySchoolEntities.

还可以通过更改 UserSettings 类型的字段的值来自定义生成的代码。 例如,如果您不想生成的代码具有完全限定的系统类型,则可将 FullyQualifySystemTypes 设置为 false

有关更多信息,请参见如何:自定义对象层代码生成(实体数据模型设计器)