我看了一眼,唯一的答案,我发现是从一年前的MSDN论坛的帖子…
我在这里很新,我不太明白关于结构注释的说明
解决方法
结构注释只是将随机xml添加到EDMX文件中. EDMX文件实际上只是XML,它有4个部分 – CSDL,MSL,SSDL和与设计器中定位元素相关的部分.
> CSDL描述实体之间的实体和关联(在设计器中定义)
> SSDL描述表和关系
> MSL描述CSDL和SSDL之间的映射
如果您首先从模型开始(您想从模型生成数据库),则只有CSDL部分,SSDL和MSL将通过一些自动进程(工作流中执行的T4模板)生成,一旦创建了SSDL,则另一个T4模板将生成用于数据库创建的sql脚本.
链接的MSDN论坛的线程中描述的结构注释是一个提示.您将结构注释放在EDMX的CSDL部分(您必须打开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”属性.此属性由用于SSDL创建的T4模板识别,它只需要此元素并将其放置到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.所有注释都可以通过某些名称值集合在元数据中访问.现在,您需要修改负责sql脚本生成的T4模板,以识别此注释,并使用注释中定义的值,而不是属性中定义的类型.您可以在以下位置找到该模板:
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生成模板更改为您修改的模板.
-- 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在开箱即用的情况下没有任何工具支持.