如何:自定义实体数据模型以使用自定义对象(实体框架)
如果您希望将自定义数据类用于 实体数据模型 (EDM),则在概念性架构定义语言 (CSDL) 文件中定义的实体类型和属性必须与自定义数据类匹配。实体框架 工具生成一组映射文件,在这些文件中,CSDL 文件中的实体类型和实体集与数据库中的表相匹配。为自定义数据类更新这些映射文件的过程如下所示:
更新 CSDL 文件以与自定义数据类相匹配。
在映射规范语言 (MSL) 文件中更新映射。
更新存储架构定义语言 (SSDL) 文件(如果需要)。
验证已更新的映射文件。
使 Visual Studio 停止生成对象层。
若要运行本主题中的示例,必须已使用 EDM 生成器 (EdmGen.exe) 实用工具或 实体数据模型向导生成了 EDM 映射文件。有关更多信息,请参见如何:使用 EdmGen.exe 生成实体数据模型(实体框架)。如果要在 Visual Studio 中使用 Entity Data Model 设计器,还必须禁用根据更新后的 CSDL 文件生成对象层。否则,您的项目中将具有重复的数据类。
更新 CSDL 文件以反映自定义数据对象
在 Visual Studio 或 notepad.exe 中打开 CSDL 文件。
重命名 EntityType 和 EntitySet 元素以反映自定义数据类的名称。
对于任何不具备相应的自定义数据类的实体,删除 EntityType 和 EntitySet 元素。
重命名每个类型的 Property 元素,以与自定义数据类中属性的名称相匹配。
对于自定义数据类中不存在的任何属性,删除 Property 元素。
保存对 CSDL 文件所做的更改。
更新 MSL 文件以将自定义数据对象映射到数据源中的对象
在 Visual Studio 或 notepad.exe 中打开 MSL 文件。
重命名 EntitySetMapping 元素和 TypeName 属性以反映自定义类的名称。
对于任何不具备相应的自定义数据类的实体,删除 EntitySetMapping 元素。
重命名每个类型的 ScalarProperty 元素,以与自定义数据类中属性的名称相匹配。
对于自定义数据类中不存在的任何属性,删除 ScalarProperty 元素。
重命名 AssociationSetMapping 中的 EndProperty 元素以反映自定义类的名称。
重命名每个 AssociationSetMapping 中的 ScalarProperty 元素,以与自定义数据类中属性的名称相匹配。
注意 请勿更改任何 ColumnName 属性。
对于自定义数据类中不存在的任何实体之间的关联,删除 AssociationSetMapping 元素。
保存对 MSL 文件所做的更改。
更新 SSDL 文件以删除自定义数据类中不存在的实体
在 Visual Studio 或 notepad.exe 中打开 SSDL 文件。
对于未映射到自定义数据类的任何实体,删除 EntityType 元素。
对于未映射到自定义数据类的属性的任何属性,删除 ScalarProperty 元素。
保存对 SSDL 文件所做的更改。
验证已更新的映射文件
在包含映射文件的目录中运行 EdmGen.exe 实用工具。使用以下命令:
%windir%\Microsoft.NET\Framework\v3.5\edmgen.exe /mode:ValidateArtifacts /inssdl:.\YourModel.ssdl /inmsl:.\YourModel.msl /incsdl:.\YourModel.csdl
注意 删除换行符并将 YourModel 替换为用于映射文件的名称。
检查输出并修复任何验证错误。
重新生成、保存和删除自动生成的对象代码
在 Visual Studio 的**“解决方案资源管理器”中,右键单击 CSDL 文件并选择**“运行自定义工具”**。
此时将基于修改后的 CSDL 文件重新生成对象层。
展开 CSDL 文件节点,打开设计器文件,将文件另存为不同的文件名。
此时将保存自动生成的对象层文件。此文件中的代码用于主题如何:将对象服务用于自定义对象 (Entity Framework) 中。
从项目中排除设计器文件。
选择 CSDL 文件,并在**“属性”**窗口中清除“自定义工具”值。
此时将防止重新生成对象层文件。若要在将来生成此文件,请在**“属性”**窗口中为自定义工具键入 EntityModelCodeGenerator,然后重复步骤 1。
示例
以下 CSDL 文件已自定义以支持 Orders 和 LineItem 自定义数据类。
<Schema Namespace="Microsoft.Samples.Edm" Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="SalesOrdersEntities">
<EntitySet Name="LineItem" EntityType="Microsoft.Samples.Edm.LineItem" />
<EntitySet Name="Order" EntityType="Microsoft.Samples.Edm.Order" />
<AssociationSet Name="FK_LineItem_Order_OrderId" Association="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId">
<End Role="Order" EntitySet="Order" />
<End Role="LineItem" EntitySet="LineItem" />
</AssociationSet>
</EntityContainer>
<EntityType Name="LineItem">
<Key>
<PropertyRef Name="LineItemId" />
</Key>
<Property Name="LineItemId" Type="Int32" Nullable="false" />
<Property Name="TrackingNumber" Type="String" MaxLength="25" />
<Property Name="Quantity" Type="Int16" Nullable="false" />
<Property Name="Product" Type="Int32" Nullable="false" />
<Property Name="Price" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="Discount" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<NavigationProperty Name="Order" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId"
FromRole="LineItem" ToRole="Order" />
</EntityType>
<EntityType Name="Order">
<Key>
<PropertyRef Name="OrderId" />
</Key>
<Property Name="OrderId" Type="Int32" Nullable="false" />
<Property Name="OrderDate" Type="DateTime" Nullable="false" />
<Property Name="DueDate" Type="DateTime" Nullable="false" />
<Property Name="ShipDate" Type="DateTime" />
<Property Name="Status" Type="Byte" Nullable="false" />
<Property Name="Customer" Type="Int32" Nullable="false" />
<Property Name="SubTotal" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="TaxAmt" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="Freight" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="ExtendedInfo" Type="Self.OrderInfo" Nullable="false" />
<NavigationProperty Name="LineItem" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId"
FromRole="Order" ToRole="LineItem" />
</EntityType>
<ComplexType Name="OrderInfo">
<Property Name="OrderNumber" Type="String" Nullable="false" MaxLength="25" />
<Property Name="PurchaseOrder" Type="String" MaxLength="25" />
<Property Name="AccountNumber" Type="String" MaxLength="15" />
<Property Name="Comment" Type="String" MaxLength="128" />
</ComplexType>
<Association Name="FK_LineItem_Order_OrderId">
<End Role="Order" Type="Microsoft.Samples.Edm.Order" Multiplicity="1" />
<End Role="LineItem" Type="Microsoft.Samples.Edm.LineItem" Multiplicity="*" />
</Association>
</Schema>
以下 MSL 文件已自定义,以将 Orders 和 LineItem 自定义数据类映射到 AdventureWorks 数据库中的 SalesOrderHeader 和 SalesOrderDetail 表。
<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
<EntityContainerMapping StorageEntityContainer="Sales" CdmEntityContainer="SalesOrdersEntities">
<EntitySetMapping Name="LineItem" StoreEntitySet="SalesOrderDetail" TypeName="Microsoft.Samples.Edm.LineItem">
<ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
<ScalarProperty Name="TrackingNumber" ColumnName="CarrierTrackingNumber" />
<ScalarProperty Name="Quantity" ColumnName="OrderQty" />
<ScalarProperty Name="Product" ColumnName="ProductID" />
<ScalarProperty Name="Price" ColumnName="UnitPrice" />
<ScalarProperty Name="Discount" ColumnName="UnitPriceDiscount" />
</EntitySetMapping>
<EntitySetMapping Name="Order" StoreEntitySet="SalesOrderHeader" TypeName="Microsoft.Samples.Edm.Order">
<ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
<ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
<ScalarProperty Name="DueDate" ColumnName="DueDate" />
<ScalarProperty Name="ShipDate" ColumnName="ShipDate" />
<ScalarProperty Name="Status" ColumnName="Status" />
<ScalarProperty Name="Customer" ColumnName="CustomerID" />
<ScalarProperty Name="SubTotal" ColumnName="SubTotal" />
<ScalarProperty Name="TaxAmt" ColumnName="TaxAmt" />
<ScalarProperty Name="Freight" ColumnName="Freight" />
<ComplexProperty Name ="ExtendedInfo" TypeName ="Microsoft.Samples.Edm.OrderInfo">
<ScalarProperty Name="OrderNumber" ColumnName="SalesOrderNumber" />
<ScalarProperty Name="PurchaseOrder" ColumnName="PurchaseOrderNumber" />
<ScalarProperty Name="AccountNumber" ColumnName="AccountNumber" />
<ScalarProperty Name="Comment" ColumnName="Comment" />
</ComplexProperty>
</EntitySetMapping>
<AssociationSetMapping Name="FK_LineItem_Order_OrderId" TypeName="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" StoreEntitySet="SalesOrderDetail">
<EndProperty Name="Order">
<ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
</EndProperty>
<EndProperty Name="LineItem">
<ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
</EndProperty>
<Condition ColumnName="SalesOrderID" IsNull="false" />
</AssociationSetMapping>
</EntityContainerMapping>
</Mapping>
以下 SSDL 文件已自定义,以使用 AdventureWorks 数据库中的 SalesOrderHeader 和 SalesOrderDetail 表支持 Orders 和 LineItem 自定义数据类。
<Schema Namespace="Microsoft.Samples.Edm.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="Sales">
<EntitySet Name="SalesOrderDetail" EntityType="Microsoft.Samples.Edm.Store.SalesOrderDetail" />
<EntitySet Name="SalesOrderHeader" EntityType="Microsoft.Samples.Edm.Store.SalesOrderHeader" />
<AssociationSet Name="FK_LineItem_Orders_OrderId" Association="Microsoft.Samples.Edm.Store.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
<End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
<End Role="SalesOrderDetail" EntitySet="SalesOrderDetail" />
</AssociationSet>
</EntityContainer>
<EntityType Name="SalesOrderDetail">
<Key>
<PropertyRef Name="SalesOrderDetailID" />
</Key>
<Property Name="SalesOrderID" Type="int" Nullable="false" />
<Property Name="SalesOrderDetailID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="CarrierTrackingNumber" Type="nvarchar" MaxLength="25" />
<Property Name="OrderQty" Type="smallint" Nullable="false" />
<Property Name="ProductID" Type="int" Nullable="false" />
<Property Name="UnitPrice" Type="money" Nullable="false" />
<Property Name="UnitPriceDiscount" Type="money" Nullable="false" />
</EntityType>
<EntityType Name="SalesOrderHeader">
<Key>
<PropertyRef Name="SalesOrderID" />
</Key>
<Property Name="SalesOrderID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="OrderDate" Type="datetime" Nullable="false" />
<Property Name="DueDate" Type="datetime" Nullable="false" />
<Property Name="ShipDate" Type="datetime" />
<Property Name="Status" Type="tinyint" Nullable="false" />
<Property Name="SalesOrderNumber" Type="nvarchar" Nullable="false" StoreGeneratedPattern="Computed" MaxLength="25" />
<Property Name="PurchaseOrderNumber" Type="nvarchar" MaxLength="25" />
<Property Name="AccountNumber" Type="nvarchar" MaxLength="15" />
<Property Name="CustomerID" Type="int" Nullable="false" />
<Property Name="SubTotal" Type="money" Nullable="false" />
<Property Name="TaxAmt" Type="money" Nullable="false" />
<Property Name="Freight" Type="money" Nullable="false" />
<Property Name="Comment" Type="nvarchar" MaxLength="128" />
</EntityType>
<Association Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
<End Role="SalesOrderHeader" Type="Microsoft.Samples.Edm.Store.SalesOrderHeader" Multiplicity="1" />
<End Role="SalesOrderDetail" Type="Microsoft.Samples.Edm.Store.SalesOrderDetail" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="SalesOrderHeader">
<PropertyRef Name="SalesOrderID" />
</Principal>
<Dependent Role="SalesOrderDetail">
<PropertyRef Name="SalesOrderID" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>