Шаблон генератора ADO.NET EntityObject

В этом разделе приводятся краткие сведения о шаблоне Генератора ADO.NET EntityObject, поставляемого вместе с Visual Studio 2010. В разделе также приводится описание настройки текстового шаблона. Шаблон Генератора ADO.NET EntityObject формирует типовые производные класса сущностей ObjectContext и EntityObject (код уровня объекта).

Шаблон Генератора ADO.NET EntityObject создает такой же код, что и код по умолчанию, создаваемый конструктором сущностей. Шаблон генератора ADO.NET EntityObject состоит из одного текстового файла шаблона: <имя модели>.tt. Шаблон <имя модели>.tt формирует один файл источника, <имя модели>.cs (или .vb), который появляется под именем <имя модели>.tt в обозревателе решений.

Общие сведения о файле <имя модели>.tt

Прежде всего код использует встроенные директивы, которые задают параметры системы обработки текстовых шаблонов для обработки шаблона. Текстовый шаблон включает TTINCLUDE-файл, который содержит классы приложения, обеспечивающие процесс создания кода. Дополнительные сведения о TTINCLUDE-файле см. в разделе Общие сведения об TTINCLUDE-файле (платформа Entity Framework).

<#@ 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, который позволяет пользователю указать, каким образом следует выписывать код. Например, этот тип определяет, используется ли «верблюжий» стиль для имен полей, или методы 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-файле. Инициализируются также некоторые локальные переменные.

<#
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 (For Each в Visual Basic) используются для вывода текста, который основывается на сведениях о метаданных, возвращенных вспомогательной функцией GetSourceSchemaTypes. Вспомогательная функция GetSourceSchemaTypes определяется в файле <имя модели>.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 и включают атрибуты, которые определяют, каким образом сложные типы на уровне объекта сопоставляются со сложными типами в концептуальной модели.

Затем определяются вспомогательные функции. Вспомогательные функции включаются в функциональные блоки в текстовых шаблонах. Теги функции класса обозначаются при помощи <#+ и #>.

Настройка кода уровня объекта

Для настройки способа формирования кода уровня объекта следует изменить TT-файл. Можно изменить имя контекста типизированного объекта, добавить новые свойства или атрибуты на типах сущностей или изменить существующие, а также сделать так, чтобы тип сущности наследовал какой-то интерфейс. Для настройки кода уровня объекта можно изменить текстовые блоки в TT-файле (текстовый блок находится за пределами тегов <# и #>).

Для изменения имени контекста типизированного объекта добавьте определенное слово (например, My) перед всеми экземплярами <#=code.Escape(container)#>. Затем, если имя контейнера в EDMX-файле — SchoolEntities, именем контейнера в созданном коде будет MySchoolEntities.

Сформированный код можно также настроить посредством изменения значений полей типа UserSettings. Например, задайте параметру FullyQualifySystemTypes значение false, если сформированный код не должен содержать полные системные типы.

Дополнительные сведения см. в разделе Как настроить создание кода уровня объекта (конструктор моделей EDM).