Зачем использовать T4 для изменения сущностей в EF? - PullRequest
1 голос
/ 21 декабря 2011

Какова действительная причина для использования ADO.NET EntityObject Generator с EF? Если вы не знаете, он генерирует файл T4, который выполняет построение сущностей из edmx. Затем вы можете изменить файл T4, чтобы изменить способ создания объектов.

Мой вопрос: кроме изменения базового класса, в котором создаются объекты (также реализующего интерфейсы) и изменения доступности объектов и / или объектов контекста и соглашений об именах, какое использование это имеет? Учитывая существующие особенности EF и частичных классов.

Я придумал 2

  1. Получите описания таблиц / столбцов из базы данных и заполните сводку по сущностям и свойствам
  2. Создайте DTO со светлым светом и выполните автоматическое сопоставление.

1 кажется слишком большой работой, учитывая, что она только обновляет комментарии к моделям, а не сам EDMX (хотя это может быть так)

2 Это даже полезно?

Ответы [ 5 ]

4 голосов
/ 21 декабря 2011

Мы сделали несколько вещей с шаблонами T4.Первый - разделить сгенерированный код на один класс на файл вместо одного массивного файла.Это просто облегчает навигацию и просмотр сущностей.

Второй, и более важный, заключается в автоматической генерации атрибутов проверки аннотации данных, таких как StringLength и Required.Это позволяет нам проверять наши сущности с помощью одного вызова функции и гарантирует, что их атрибуты проверки всегда синхронизируются с базой данных (поскольку, например, если мы изменим длину столбца в БД, сгенерированный атрибут StringLength () будетобновляется, когда мы делаем «Обновление модели из базы данных»).

На предыдущей работе мы также добавили базовые классы и интерфейсы для сущностей, как вы упомянули в своем вопросе.


Вот фрагмент из нашего шаблона T4, который проверяет необходимые столбцы и длины строк и добавляет необходимые атрибуты проверки:

    ''' <summary>
    ''' <#=SummaryComment(primitiveProperty)#>
    ''' </summary><#=LongDescriptionCommentElement(primitiveProperty, 1)#>
    <EdmScalarPropertyAttribute(EntityKeyProperty:=<#=code.CreateLiteral(ef.IsKey(primitiveProperty))#>, IsNullable:=<#=code.CreateLiteral(ef.IsNullable(primitiveProperty))#>)>
    <DataMemberAttribute()>
<#+
  ' begin required attribute
  If Not ef.IsNullable(primitiveProperty) and not ef.IsKey(primitiveProperty) then
#>
<#+
    If ef.ClrType(primitiveProperty.TypeUsage) = GetType(Guid) Then
#>
    <GuidRequiredAttribute(ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> is required")>
<#+
    Else
#>
    <RequiredAttribute(ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> is required")>
<#+
    End If
#>
<#+
  End If
    If HasMaxLength(primitiveProperty.TypeUsage) then
    Dim d = MaxLength(primitiveProperty.TypeUsage)
#>
    <StringLengthAttribute(<#=d#>, ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> cannot be longer than <#=d#> characters")>
<#+
    End If
#>
1 голос
/ 09 июля 2012

Я знаю, что это старый вопрос, но мне хотелось бы найти эту информацию, когда я начинал. В нашем случае, когда у нас есть клиент Win32 Delphi в нашем многоуровневом решении, я использовал шаблоны (в C #) для генерации классов DTO в .Net и их коллег из win32.
Это позволяет нам инкапсулировать функциональность CRUD на клиенте, используя в основном автоматически сгенерированный код Delphi:

procedure Delete;
class function DeleteDto(const _dESPATCHID: integer)  : boolean;
class function GetNextID  : integer;
class function Get(const _dESPATCHID: integer) : TDtoDESPATCH; overload;    
class function Collection(const __filterXml: string): TList<TDtoDESPATCH>;
function Load: boolean; overload;
function Populate(_primaryDict : TDictionary<string, Variant>) : boolean;
function Save : boolean; overload;


Отслеживание изменений с клиента также может быть автоматизировано, поэтому каждый установщик свойств помечает измененное свойство, чтобы гарантировать, что обновляются только измененные свойства. Например:

procedure TDtoDESPATCH.SetSCT_STATUS(const value : string);
begin
    if (self.IsLoaded) and (inherited SCT_STATUS <> value) then
      begin
        TrackChange('SCT_STATUS');
        self.Modified:= True;
      end;
    inherited SCT_STATUS := value;
end;


На стороне сервера другой шаблон заботится обо всех операциях CRUD в автоматически сгенерированной службе WCF, которая также отображается как веб-служба asmx. Интерфейс, методы WCF и все аннотации генерируются из шаблона.

// convert to entity
var _entity = _dto.ToEntity();
if(exists)
{
    Global.LogActivity(string.Format("{0} - profile {1}, updating DESPATCH: {2}", racID, profile, _dto.ChangedProperties ));
    // Attach the entity to the db
    db.DESPATCHes.Attach(_entity);
    // Change tracking
    ChangeTracking<DESPATCH>(_dto.ModifiedProperties, db, _entity);
}


В сценарии, где WIN32 должен быть частью решения, ручное кодирование всего этого было бы (хуже) кошмаром.

1 голос
/ 21 декабря 2011

Шаблон T4 заменяет пользовательский инструмент, используемый в EFv1 для генерации кода за файлом (файл .designer.cs со всеми классами). Основным преимуществом T4 является то, что вы можете изменить его для каждого проекта, просто изменив текстовый файл .tt. В случае пользовательских инструментов изменения были в основном невозможны.

С T4 у вас есть полный контроль над классами сущностей, сгенерированными из вашего EDMX. Это преобразование EDMX в файлы C # или VB.NET. Шаблон по умолчанию создает файлы классов с функциями, необходимыми большинству разработчиков, но если вам нужно что-то еще, вы можете просто зайти в свой файл .tt и добавить его.

Возможности для изменений не ограничены, потому что сам файл EDMX является расширяемым. За EDMX находится всего лишь XML-файл, и вы можете включить в этот файл свои собственные пользовательские XML-элементы (у него есть некоторые ограничения, но это возможно - здесь - это некоторый пример генерации SQL в подходе модели сначала). Если у вас есть пользовательские элементы в EDMX, вы можете использовать их в шаблоне T4 в качестве логики принятия решения для дополнительных функций, которые вы хотите включить в сгенерированный код. Конструктор сущностей также является расширяемым - вы можете создавать собственные расширения, которые будут храниться как пользовательские элементы в файле EDMX. Расширения EDMX и Entity Designer хорошо описаны в книге Entity Framework в действии .

1 голос
/ 21 декабря 2011

Ну, причина в том, что вы можете делать с этим все что угодно. Так почему бы и нет? Конечно, использование T4 очень ограничено некоторыми частными случаями, и большую часть времени его не имеет смысла использовать. С другой стороны, вы можете сделать что-нибудь интересное с ним. Например, вы можете определить некоторые пользовательские вещи. Допустим, в вашей таблице есть столбец Sort. Затем вы можете определить функцию запроса, в которой она автоматически сортирует каждую запись, если этот столбец существует. Может быть, слишком тривиально для примера, но есть множество других странных архитектур, где это имеет гораздо больше смысла.

Вы также можете использовать другие средства генерации кода без EF. Так что это, безусловно, здесь для полноты и расширяемости.

0 голосов
/ 18 декабря 2017

Я использовал их немного для генерации кода, который будет полезен для нас на уровне Datalayer.

Изменение того, реализуют ли они дополнительные контракты (интерфейсы), добавление методов, аннотаций и, в случае не многослойного приложения (и НЕ рекомендуется после этого), добавление уведомления об изменении свойства.

Добавив некоторые из этих элементов в поколение в Datalayer, я смог использовать шаблон в проекте Model для генерации кода котельной плиты и на этом уровне.

Итог: если вы можете безопасно заставить компьютер кодировать для вас, то это того стоит. В нашем случае 80% основной сантехнической работы может быть связано с кодом - если он неправильный, его обычно очень легко исправить и восстановить.

...