LINQtoSQL: Модификация в соответствии с требованиями код, генерируемый конструктором - Сценарий 2 – Существенные изменения

ОГЛАВЛЕНИЕ

Сценарий 2 – Существенные изменения

В этом сценарии вас устраивает сгенерированный Microsoft код, но вам нужен дополнительный код. Примером дополнительного кода может быть добавление метода к каждому классу, сгенерированному из таблицы, или создание сценариев SQL для объектов базы данных.

Самый простой способ сделать это – связать файл DBML с двумя генераторами кода. Первый вызывает генератор кода Microsoft, и вы можете захотеть немного изменить его работу, как в сценарии 1. Второй генерирует дополнительный код.

Чтобы правильно скомпоновать генератор кода для файла DBML, вам нужно иметь возможность десериализовать его в упорядочиваемый экземпляр класса. Это достигается путем включения схемы в проект генератора кода, который создает упорядочиваемые классы с помощью этой схемы. Второй генератор кода десериализует файл DBML в такой класс и затем использует его для генерации требуемого кода.

Файл схемы DBML можно найти в C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\DbmlSchema.xsd,CustomizeDesigners к Dbml\DbmlSchema.xsd. Он связан с генератором кода CustomizeDesigners\XsdRenderers.rgt, который вызывает тот же механизм, что и xsd.exe, чтобы создавать сериализуемые классы с помощью схем. Раскройте список потомков элементов проекта для DbmlSchema.xsd, чтобы увидеть сериализуемые классы. предполагая, что вы установили Visual Studio в каталог по умолчанию. Эта схема была добавлена в проект

Business\Scenario2\CustomersLINQ.dbml связан с двумя генераторами кода (щелкните на нем правой кнопкой мыши и нажмите "Присоединенные рендереры...", чтобы проверить), и два файла .cs будут созданы/обновлены, когда вы сохраните их. Файл Business\Scenario2\CustomersLINQ.Designer.csCustomizeDesigners\Scenario2\SmallChangesToDefaultLINQtoSQL.cs таким же образом, как и для сценария 1. генерируется с помощью

Файл Business\Scenario2\CustomersLINQ.Hello.cs генерируется с помощью CustomizeDesigners\Scenario2\AddHelloMethodToTables.rgt. Это файл шаблона генератора кода, который выглядит почти как страница ASPX. Также есть код, отвечающий за логику работы, хранящийся в файле CustomizeDesigners\Scenario2\AddHelloMethodToTables.rgt.cs. Этот код написан вручную. CustomizeDesigners\Scenario2\AddHelloMethodToTables.Designer.cs содержит код шаблона. Вместе с кодом, отвечающим за логику работы, он формирует класс, который будет вызван, когда файл DBML будет сохраняться.

Шаблон генератора кода CustomizeDesigners\Scenario2\AddHelloMethodToTables.rgt выглядит так:

<%@ Template Language="C#" ClassName="AddHelloMethodToTables" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="CustomizeDesigners.Dbml" %>
 
// -------------------------------------------------------
// Автоматически сгенерировано Reegenerator
// Generator: CustomizeDesigners.Scenario2.AddMethodToTables
// Generation date: <%= System.DateTime.Now.ToString("yyyy-MM-dd hh:mm") %>
// Generated by: <%= System.Security.Principal.WindowsIdentity.GetCurrent().Name %>
// -------------------------------------------------------

namespace <%= base.ProjectItem.CodeNamespace %>
{
<% RenderTables(); %>
}

<%@ Method Name="RenderTable" %>
    <%@ Parameter Name="table" Type="Table" %>
    partial class <%= table.Type.Name %>
    {
        public string Hello()
        {
            return "Hello from table <%= table.Type.Name %>";
        }
    }
<%/ Method %>

В отличие от ASPX, вы можете определить методы визуализации, которые помогут вам разбить работу по генерации кода на много более легко управляемых частей. Заметим, что  <% RenderTables(); %> вызывается под пространством имен. Он вызывает функцию, которая написана  вручную в части кода, отвечающей за логику работы.

Часть кода, отвечающего за логику работы шаблона Scenario2\AddHelloMethodToTables.rgt.cs, выглядит так:

public partial class AddHelloMethodToTables
{
    /// <summary>
    /// Элемент базы данных десериализуется из файла dbml.
    /// </summary>
    Database _database = null;
    /// <summary>
    /// Выполняется перед визуализацией. Десериализует файл dbml file в свойство _database.
    /// </summary>
    public override void PreRender()
    {
        base.PreRender();
        // десериализует файл dbml в свойство private.
        this._database = DbmlSchemaFactory.Create<Database>(base.ProjectItem);
    }
    /// <summary>
    /// Отображает все таблицы.
    /// </summary>
    private void RenderTables()
    {
        if (this._database.Table == null)
            return;
        foreach (Table table in this._database.Table)
        {
            RenderTable(table);
        }
    }
}

Файл DBML десериализуется в свойство _database перед выполнением генерации кода. Учтите, что реализация RenderTables вызывается из файла шаблона. В свою очередь, он вызывает RenderTable(Table table), который определен в шаблоне.

Чтобы проверить это, отредактируйте Business\Scenario2\CustomersLINQ.dbml, сохраните его, раскройте список его потомков и проверьте содержимое двух cs-файлов потомков.

Для отладки установите точку останова в методе PreRender, запустите сеанс отладки, загрузите то же самое решение во второй экземпляр Visual Studio и выполните те же действия, что и при тестировании.