Anotasi struktural - bagus. Ini adalah pertama kalinya saya mendengar tentang fitur ini tetapi berhasil. Saya baru saja mencobanya. Saya akan mencoba menjelaskannya sedikit.
Anotasi struktural hanyalah xml acak yang ditambahkan ke file EDMX. File EDMX sebenarnya hanya XML yang memiliki 4 bagian - CSDL, MSL, SSDL dan bagian yang terkait dengan elemen pemosisian di desainer.
- CSDL menjelaskan entitas dan asosiasi antar entitas (didefinisikan dalam desainer)
- SSDL menjelaskan tabel dan relasi
- MSL menjelaskan pemetaan antara CSDL dan SSDL
Jika Anda memulai dengan model terlebih dahulu (Anda ingin membuat database dari model Anda), Anda hanya memiliki bagian CSDL dan SSDL dan MSL akan dihasilkan oleh beberapa proses otomatis (templat T4 dijalankan dalam alur kerja) setelah SSDL dibuat, templat T4 lain akan menghasilkan Skrip SQL untuk pembuatan database.
Anotasi struktural yang dijelaskan dalam utas forum MSDN tertaut adalah petunjuk. Anda akan menempatkan anotasi struktural ke dalam bagian CSDL dari EDMX (Anda harus membuka EDMX sebagai XML - klik file di solution explorer dan pilih Buka dengan). CSDL pengujian saya menjelaskan entitas Pengguna tunggal dengan tiga properti (entitas terlihat pada tangkapan layar nanti di jawaban):
<!-- 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>
Saya telah menambahkan definisi namespace khusus di Schema
elemen:xmlns:custom="http://tempuri.org/custom"
dan anotasi struktural khusus yang ditentukan untuk CreatedAt
properti:
<Property Type="DateTime" Name="CreatedAt" Nullable="false">
<custom:SqlType edmx:CopyToSSDL="true">Date</custom:SqlType>
</Property>
Nama namespace atau elemen yang digunakan untuk anotasi struktural tidak penting - terserah Anda nama apa yang Anda gunakan. Satu-satunya hal yang penting adalah edmx:CopyToSSDL="true"
atribut. Atribut ini dikenali oleh template T4 yang digunakan untuk pembuatan SSDL dan hanya mengambil elemen ini dan menempatkannya ke SSDL. SSDL yang dihasilkan terlihat seperti:
<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>
Satu-satunya poin adalah memindahkan anotasi struktural ke SSDL. Semua anotasi dapat diakses dalam metadata melalui beberapa kumpulan nilai nama. Sekarang Anda perlu memodifikasi template T4 yang bertanggung jawab untuk pembuatan skrip SQL untuk mengenali anotasi ini dan menggunakan nilai yang ditentukan dalam anotasi alih-alih tipe yang ditentukan di properti. Anda dapat menemukan template di:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\DBGen\SSDLToSQL10.tt
Salin file template ke lokasi baru (agar Anda tidak mengubah yang asli) dan ganti pembuatan tabel default dengan ini:
-- 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
Sekarang poin terakhir adalah mengubah template yang digunakan untuk pembuatan skrip SQL. Buka file EDMX di desainer dan buka properti model (cukup klik di suatu tempat di desainer saat Anda membuka jendela properti). Ubah Template Generasi DDL ke template yang Anda modifikasi.
Jalankan Hasilkan Basis Data dari Model dan itu akan membuat skrip SQL yang berisi:
-- Creating table 'UsersSet'
CREATE TABLE [dbo].[UsersSet] (
[Id] int IDENTITY(1,1) NOT NULL,
[Login] nvarchar(max) NOT NULL,
[CreatedAt] Date NOT NULL
);
GO
Ini mungkin fitur EDMX paling canggih dan tersembunyi yang pernah saya lihat. Anotasi bersama dengan templat T4 khusus dapat memberi Anda banyak kendali atas pembuatan kelas dan SQL. Saya dapat membayangkan menggunakan ini untuk mendefinisikan misalnya indeks basis data atau kunci unik saat menggunakan model terlebih dahulu atau menambahkan secara selektif beberapa atribut khusus ke kelas POCO yang dihasilkan.
Alasan mengapa ini sangat tersembunyi adalah karena tidak ada dukungan alat di VS yang siap pakai untuk menggunakan ini.