Как использовать структурные аннотации для установки типа SQL в Date в модели сначала подход - PullRequest
12 голосов
/ 06 мая 2011

Можно ли установить тип на просто дату (НЕ на дату / время) через конструктор структуры сущностей?

Я осмотрелся, и единственный ответ, который я нашел, - это сообщение с форума MSDN год назад ...

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/28e45675-f64b-41f0-9f36-03b67cdf2e1b

I 'Я очень новичок здесь, и я не очень понимаю инструкции, где они говорят о структурных аннотациях ...

Я могу просмотреть сгенерированный сценарий SQL и изменить каждую строку, но лучше не делать этого ...

Ответы [ 2 ]

19 голосов
/ 08 мая 2011

Структурная аннотация - приятно.Впервые слышу об этой функции, но она работает.Я только что попробовал это.Я попытаюсь объяснить это немного.

Структурные аннотации - это просто случайные xml, добавленные в файл EDMX.Файл EDMX на самом деле представляет собой всего лишь XML, который состоит из 4 частей - CSDL, MSL, SSDL и части, связанной с позиционированием элементов в конструкторе.

  • CSDL описывает сущности и ассоциации между сущностями (определенные в конструкторе)
  • SSDL описывает таблицы и отношения
  • MSL описывает отображение между CSDL и SSDL

Если вы начинаете с модели в первую очередь (вы хотите сгенерировать базу данных из вашей модели), выиметь только часть CSDL, и SSDL и MSL будут сгенерированы некоторым автоматическим процессом (шаблоны T4, выполняемые в рабочем процессе) после создания SSDL, другой шаблон T4 сгенерирует сценарий SQL для создания базы данных.

Структурная аннотация, описанная в связанном MSDNТема форума - это подсказка.Вы поместите структурную аннотацию в CSDL-часть EDMX (необходимо открыть EDMX в формате XML - щелкните файл в обозревателе решений и выберите «Открыть с помощью»).Мой тестовый CSDL описывает одну сущность пользователя с тремя свойствами (сущность видна на снимке экрана ниже в ответе):

<!-- CSDL content -->
<edmx:ConceptualModels>
  <Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" 
          xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" 
          xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
          xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
          xmlns:custom="http://tempuri.org/custom"
          Namespace="Model" Alias="Self" >
    <EntityContainer Name="ModelContainer" annotation:LazyLoadingEnabled="true">
      <EntitySet Name="UsersSet" EntityType="Model.User" />
    </EntityContainer>
    <EntityType Name="User">
      <Key>
        <PropertyRef Name="Id" />
      </Key>
      <Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
      <Property Type="String" Name="Login" Nullable="false" />
      <Property Type="DateTime" Name="CreatedAt" Nullable="false">
        <custom:SqlType edmx:CopyToSSDL="true">Date</custom:SqlType>
      </Property>
    </EntityType>
  </Schema>
</edmx:ConceptualModels>

Я добавил определение пользовательского пространства имен в элементе Schema: xmlns:custom="http://tempuri.org/custom" и определил пользовательскую структуруаннотация для CreatedAt свойство:

<Property Type="DateTime" Name="CreatedAt" Nullable="false">
   <custom:SqlType edmx:CopyToSSDL="true">Date</custom:SqlType>
</Property>

Имя пространства имен или элемента, используемого для структурной аннотации, не имеет значения - вам решать, какие имена вы используете.Единственная важная вещь - это атрибут edmx:CopyToSSDL="true".Этот атрибут распознается шаблоном T4, используемым для создания SSDL, и он просто берет этот элемент и помещает его в SSDL.Сгенерированный SSDL выглядит следующим образом:

<Schema Namespace="Model.Store" Alias="Self" 
        Provider="System.Data.SqlClient" ProviderManifestToken="2008" 
        xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" 
        xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
  <EntityContainer Name="ModelStoreContainer">
    <EntitySet Name="UsersSet" EntityType="Model.Store.UsersSet" store:Type="Tables" Schema="dbo" />
  </EntityContainer>
  <EntityType Name="UsersSet">
    <Key>
      <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
    <Property Name="Login" Type="nvarchar(max)" Nullable="false" />
    <Property Name="CreatedAt" Type="datetime" Nullable="false">
      <custom:SqlType xmlns:custom="http://tempuri.org/custom">Date</custom:SqlType>
    </Property>
  </EntityType>
</Schema>

Единственной точкой было перемещение структурной аннотации в SSDL.Все аннотации доступны в метаданных через некоторую коллекцию значений имен.Теперь вам нужно изменить шаблон T4, отвечающий за генерацию сценария SQL, чтобы распознать эту аннотацию и использовать значение, определенное в аннотации, вместо типа, определенного в свойстве.Вы можете найти шаблон в:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\DBGen\SSDLToSQL10.tt

Скопировать файл шаблона в новое место (чтобы не изменять исходный) и заменить создание таблицы по умолчанию следующим:

-- Creating table '<#=tableName#>'
CREATE TABLE <# if (!IsSQLCE) {#>[<#=schemaName#>].<#}#>[<#=tableName#>] (
<#
        for (int p = 0; p < entitySet.ElementType.Properties.Count; p++)
        {
            EdmProperty prop = entitySet.ElementType.Properties[p];
#>
    [<#=Id(prop.Name)#>] <#
            if (prop.MetadataProperties.Contains("http://tempuri.org/custom:SqlType"))
            {
                MetadataProperty annotationProperty = prop.MetadataProperties["http://tempuri.org/custom:SqlType"];
                XElement e = XElement.Parse(annotationProperty.Value.ToString());
                string value = e.Value.Trim();
    #>
    <#=value#> <# } else { #> <#=prop.ToStoreType()#> <# } #> <#=WriteIdentity(prop, targetVersion)#> <#=WriteNullable(prop.Nullable)#><#=(p < entitySet.ElementType.Properties.Count - 1) ? "," : ""#>
<#
        }
#>
);
GO

Теперь последний пункт - изменение шаблона, используемого для генерации SQL-скрипта.Откройте файл EDMX в конструкторе и перейдите к свойствам модели (просто щелкните где-нибудь в конструкторе, когда у вас открыто окно свойств).Измените шаблон генерации DDL на шаблон, который вы изменили.

enter image description here

Выполнить Создать базу данных из модели , и она создаст сценарий SQL, содержащий:

-- Creating table 'UsersSet'
CREATE TABLE [dbo].[UsersSet] (
    [Id]  int  IDENTITY(1,1) NOT NULL,
    [Login]  nvarchar(max)   NOT NULL,
    [CreatedAt]     Date   NOT NULL
);
GO

Это, вероятно, самый продвинутый искрытой возможности EDMX я еще не видел.Аннотации вместе с настраиваемыми шаблонами T4 могут дать вам большой контроль над генерацией классов и SQL.Я могу представить себе использование этого для определения, например, индексов базы данных или уникальных ключей при первом использовании модели или выборочного добавления некоторых пользовательских атрибутов к сгенерированным классам POCO.

Причина, по которой это так скрыто, заключается в том, что вVS из коробки, чтобы использовать это.

0 голосов
/ 23 сентября 2013

Из NuGet ищите TiraggoEdmx, он очень хорошо обрабатывает всю информацию низкого уровня из ваших файлов EDMX.Смотри http://brewdawg.github.io/Tiraggo.Edmx/

...