Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да използвам структурни анотации, за да задам SQL тип на Дата в първия подход на модела

Структурна анотация - хубава. За първи път чувам за тази функция, но работи. Току що го пробвах. Ще се опитам да го обясня малко.

Структурните анотации са просто случаен 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 - щракнете върху файла в Solution Explorer и изберете Отваряне с). Моят тестов 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 към шаблона, който сте променили.

Стартирайте Генериране на база данни от модел и ще създаде 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 извън кутията, за да се използва това.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да съпоставите множество дялове в една файлова група в SQL Server (T-SQL)

  2. Вземете времева разлика между група записи

  3. SQL:Преобразуване на цяло число в шестнадесетичен низ?

  4. Добра практика ли е REPLACE INTO?

  5. странни скриптове, генерирани от SQL Server при експортиране на задание