sql >> Databáze >  >> RDS >> Sqlserver

Jak mohu pomocí strukturálních poznámek nastavit typ SQL na Datum v přístupu prvního modelu

Strukturální anotace - pěkné. O této funkci slyším poprvé, ale funguje. Právě jsem to zkusil. Pokusím se to trochu vysvětlit.

Strukturální anotace jsou pouze náhodné xml přidané do souboru EDMX. Soubor EDMX je ve skutečnosti pouze XML, který má 4 části – CSDL, MSL, SSDL a část související s prvky polohování v návrháři.

  • CSDL popisuje entity a asociace mezi entitami (definované v návrháři)
  • SSDL popisuje tabulky a vztahy
  • MSL popisuje mapování mezi CSDL a SSDL

Pokud nejprve začnete s modelem (chcete vygenerovat databázi ze svého modelu), máte pouze část CSDL a SSDL i MSL budou generovány nějakým automatickým procesem (šablony T4 spuštěné ve workflow), jakmile je vytvořen SSDL, vygeneruje se další šablona T4 SQL skript pro vytvoření databáze.

Strukturální anotace popsaná v propojeném vláknu fóra MSDN je nápovědou. Strukturální anotaci umístíte do CSDL části EDMX (musíte otevřít EDMX jako XML - klikněte na soubor v průzkumníku řešení a zvolte Otevřít s). Můj testovací CSDL popisuje jednu entitu uživatele se třemi vlastnostmi (entita je viditelná na snímku obrazovky později v odpovědi):

<!-- 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>

Přidal jsem vlastní definici jmenného prostoru do Schema prvek:xmlns:custom="http://tempuri.org/custom" a definovala vlastní strukturální anotace pro CreatedAt vlastnost:

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

Název jmenného prostoru nebo prvku použitého pro strukturální anotaci nejsou důležité - je zcela na vás, jaké názvy použijete. Jediná důležitá věc je edmx:CopyToSSDL="true" atribut. Tento atribut je rozpoznán šablonou T4 použitou pro vytvoření SSDL a pouze vezme tento prvek a umístí jej do SSDL. Vygenerovaný SSDL vypadá takto:

<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>

Jediným bodem bylo přesunutí strukturální anotace do SSDL. Všechny anotace jsou přístupné v metadatech prostřednictvím kolekce hodnot názvu. Nyní musíte upravit šablonu T4 zodpovědnou za generování skriptu SQL, aby tuto anotaci rozpoznala a místo typu definovaného ve vlastnosti použila hodnotu definovanou v anotaci. Šablonu najdete v:

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

Zkopírujte soubor šablony do nového umístění (abyste nezměnili to původní) a nahraďte výchozí vytvoření tabulky tímto:

-- 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

Nyní posledním bodem je změna šablony používané pro generování SQL skriptu. Otevřete soubor EDMX v návrháři a přejděte do vlastností modelu (stačí kliknout někam do návrháře, když máte otevřené okno vlastností). Změňte šablonu generování DDL na šablonu, kterou jste upravili.

Spusťte Generovat databázi z modelu a vytvoří SQL skript obsahující:

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

Toto je pravděpodobně nejpokročilejší a nejskrytější funkce EDMX, kterou jsem zatím viděl. Anotace spolu s vlastními šablonami T4 vám mohou poskytnout velkou kontrolu nad generováním tříd i SQL. Dokážu si představit, že to použiji k definování například databázových indexů nebo jedinečných klíčů při použití modelu jako prvního nebo k selektivnímu přidání některých vlastních atributů do generovaných tříd POCO.

Důvodem, proč je to tak skryté, je to, že ve VS neexistuje žádná podpora nástrojů, která by to mohla použít.



  1. PostgreSQL - Přidejte klíč ke každému objektu pole JSONB

  2. Přejmenování více sloupců v jednom příkazu pomocí PostgreSQL

  3. Django:Unbuffered mysql dotaz

  4. Jak zkontrolovat, zda je proměnná NULL, a poté ji nastavit pomocí uložené procedury MySQL?