Entity Framework的核心 – EDM(Entity Data Model)
EDM概述
实体数据模型,简称EDM,由三个概念组成。概念模型由概念架构定义语言文件 (.csdl)来定义,映射由映射规范语言文件 (.msl),存储模型(又称逻辑模型)由存储架构定义语言文件 (.ssdl)来定义。这三者合在一起就是EDM模式。EDM模式在项目中的表现形式就是扩展名为.edmx的文件。这个包含EDM的文件可以使用Visual Studio中的EDM设计器来设计。由于这个文件本质是一个xml文件,可以手工编辑此文件来自定义CSDL、MSL与SSDL这三部分。下面详细分析一下这个xml文件及三个其重要组成部分:
这个设计器生成的文件的注释可以使你很清楚的明白这个EDM文件的组成。一点点分析一下,第一行表明这是一个xml文件。
1 <?xmlversion="1.0"encoding="utf-8"?>
以下这一行是EDM的根节点,定义了一个表明版本的属性及这个EDM使用的命名空间:
1 <edmx:EdmxVersion="1.0"xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
接下来由注释可以看到EDM被分为两部分,第一部分是EDM的核心,第二部分用于实体设计器,这一部分不用研究。
第一部分中节点 <edmx:Runtime> 下定义了以下三部分:
EDM之CSDL
CSDL定义了EDM或者说是整个程序的灵魂部分 – 概念模型。当前流行的软件设计方法通常都是由设计其概念模型起步。说概念模型可能比较抽象一个更容易接受的名字就是实体类。实体类是面向对象设计中一个最根本的组成部分,其体现了现实世界中对象作为一种计算中可以表示的对象设计方法。而EDM的CSDL就是要达到这样一个目的。这个在下文介绍Entity Framework优点时另有说明。
这个文件完全以程序语言的角度来定义模型的概念。即其中定义的实体、主键、属性、关联等都是对应于.NET Framework中的类型。下面xml element来自作业提交系统(有删节):
1 <!-- CSDL content --> 2 <edmx:ConceptualModels> 3 <Schema Namespace="ASSModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm"> 4 <EntityContainer Name="ASSEntities"> 5 <FunctionImport Name="GETHOUSEWORKDONE" EntitySet="UpAssignments" ReturnType="Collection(Self.UpAssignments)"> 6 <Parameter Name="StuID" Type="Int32" Mode="In" /> 7 <Parameter Name="ClassID" Type="Int32" Mode="In" /> 8 <Parameter Name="Semester" Type="String" Mode="In" /> 9 </FunctionImport> 10 <!-- 以上删节 – 5个存储过程 --> 11 12 <EntitySet Name="Assignments" EntityType="ASSModel.Assignments" /> 13 <EntitySet Name="Classes" EntityType="ASSModel.Classes" /> 14 <EntitySet Name="Courses" EntityType="ASSModel.Courses" /> 15 <EntitySet Name="SetCourses" EntityType="ASSModel.SetCourses" /> 16 <EntitySet Name="Students" EntityType="ASSModel.Students" /> 17 <EntitySet Name="Teachers" EntityType="ASSModel.Teachers" /> 18 <EntitySet Name="UpAssignments" EntityType="ASSModel.UpAssignments" /> 19 20 <AssociationSet Name="FK_SetCourses_Classes" Association="ASSModel.FK_SetCourses_Classes"> 21 <End Role="Classes" EntitySet="Classes" /> 22 <End Role="SetCourses" EntitySet="SetCourses" /> 23 </AssociationSet> 24 <!-- 以上删节 – 6个关系集 --> 25 26 </EntityContainer> 27 28 <!-- 以下保留一个EntityType作为示例 --> 29 <EntityType Name="Students"> 30 <Key> 31 <PropertyRef Name="StuID" /> 32 </Key> 33 <Property Name="StuID" Type="Int32" Nullable="false" /> 34 <Property Name="StuName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="true" /> 35 <Property Name="Pswd" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="true" /> 36 <NavigationProperty Name="Classes" Relationship="ASSModel.FK_Students_Classes" FromRole="Students" ToRole="Classes" /> 37 <NavigationProperty Name="UpAssignments" Relationship="ASSModel.FK_UpAssignments_Students" FromRole="Students" ToRole="UpAssignments" /> 38 </EntityType> 39 40 <!-- 仅保留与上文AssociationSet对应的Association --> 41 <Association Name="FK_SetCourses_Classes"> 42 <End Role="Classes" Type="ASSModel.Classes" Multiplicity="1" /> 43 <End Role="SetCourses" Type="ASSModel.SetCourses" Multiplicity="*" /> 44 </Association> 45 </Schema> 46 </edmx:ConceptualModels>
这部分XML文档,Schema是CSDL的根元素,其中定义的Namespace是用于ObjectContext与EntityClass的命名空间,Alias-别名为此命名空间Namespace指定一个易记的名称,在定义Alias之后,在此Schema内的Element均可以该Alias作为Namespace的别名。Alias的使用可以参考如下xml element:
1 <FunctionImportName="GETHOUSEWORKDONE"EntitySet="UpAssignments"ReturnType="Collection(Self.UpAssignments)">
在这个根元素的内部的文档结构第一部分 – 实体容器大致如下:
1 <EntityContainer /> 2 <FunctionImport /> 3 <EntitySet /> 4 <AssociationSet /> 5 </EntityContainer>
下面的表格说明了这些节点及其属性的作用
EntityContainer |
|||
Name |
EntityContainer的名称,其将作为产生的ObjectContext类的名称 |
||
EntitySet |
|||
Name |
ObjectContext内与此Entity类型对应的属性名 |
||
EntityType |
ObjectContext内与此Entity类型对应的属性的类型 |
||
AssociationSet |
|||
End |
有两个End子节点,分别描述建立此关系的两个EntitySet |
||
Role |
对应到Association中End节的Role属性,起到将AssociationSet与Association相关连的作用。 |
||
FunctionImport |
详见存储过程设计部分 |
可以看出,Entity与Assciation都被分开定义与两个部分,这样设计是出于当有多个EntityContainer时,其中的EntitySet或AssociationSet可以共享Entity或Association的定义。
接下来看一下CSDL中最后一部分,Entity与Association的定义。
首先是Entity:
1 <EntityType Name="Students"> 2 <Key> 3 <PropertyRef Name="StuID" /> 4 </Key> 5 <Property Name="StuID" Type="Int32" Nullable="false" /> 6 <Property Name="StuName" Type="String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="true" /> 7 <Property Name="Pswd" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="true" /> 8 <NavigationProperty Name="Classes" Relationship="ASSModel.FK_Students_Classes" FromRole="Students" ToRole="Classes" /> 9 <NavigationProperty Name="UpAssignments" Relationship="ASSModel.FK_UpAssignments_Students" FromRole="Students" ToRole="UpAssignments" /> 10 </EntityType>
下表说明了其属性及其子节点与子节点的属性的含义:
EntityType |
|||
Name |
Entity Class的名称 |
||
Abstract |
是否为抽象类 |
||
BaseType |
父类 |
||
Key |
主键 |
||
Property |
主键之属性 |
||
Name |
属性名 |
||
Property |
属性 |
||
Name |
属性名 |
||
Type |
属性类型 |
||
Nullable |
是否允许null |
||
MaxLength |
属性最大长度 |
||
FixLength |
是否固定长度 |
||
NavigationProperty |
关系属性 |
||
Name |
属性名 |
||
Relationship |
对应的Association |
||
FromRole、ToRole |
区别关系两方的父与子 |
最后Association节,这是真正定义关系的地方。首先看示例:
1 <!-- 仅保留与上文AssociationSet对应的Association --> 2 <Association Name="FK_SetCourses_Classes"> 3 <End Role="Classes" Type="ASSModel.Classes" Multiplicity="1" /> 4 <End Role="SetCourses" Type="ASSModel.SetCourses" Multiplicity="*" /> 5 </Association>
这一节符合以下结构:
1 <Association> 2 <End /> 3 <ReferentialConstraint> 4 <Principal> 5 <PropertyRef /> 6 </Principal> 7 <Dependent> 8 <PropertyRef /> 9 </Dependent> 10 </ReferentialConstraint> 11 </Association>
属性及其子元素属性的说明:
Association |
||||
Name |
Association的名称 |
|||
End |
类似于AssociationSet,Association也有两个End节点。 |
|||
Name |
End名称 |
|||
Type |
EntityType的名称 |
|||
Role |
此End的Role,与AssociationSet的End的Role属性相联系 |
|||
Multiplicity |
关联多重性,值为0、1或* |
|||
ReferentialConstraint |
外键条件限制 |
|||
Principal |
主要条件 |
|||
Role |
对应于End中的Role |
|||
PropertyRef |
外键属性 |
|||
Name |
属性名称 |
|||
Dependent |
依存条件 |
|||
Role |
对应于End中的Role |
|||
PropertyRef |
外键属性 |
|||
Name |
属性名 |
另外上面示例未涉及的概念,如下:
视图
在EDM设计器中添加视图基本与添加实体表一致,所生成的xml自行对照。某些环境下可能无法添加视图,原因未知,另外对于没有主键的表目前版本EntityFramework支持不好,在设计器中无法添加,及时通过手工编辑xml的方式强行添加,在使用过程中也会出现问题。
ComplexType(复杂类型)
按MSDN中的例子,先描述如下场景。在一个销售系统中我们需要在一个订单中包含一个描述客户地址的实体,而这个实体又能良好的与存储模型映射起来,由于数据库不支持地址这种类型,所以我们可以将地址的每个字段与数据库相映射。且在概念模型中,及在C#代码可以控制的范围内,地址仍然作为一个独立的类型存在。由于EDM设计器不支持以可视化方式创建Complex Type,我们需要手动编辑CSDL与MSL来完成复杂类型的创建与映射。这部分示例将在介绍MSL后给出。
EDM之SSDL
这个文件中描述了表、列、关系、主键及索引等数据库中存在的概念。
1 <!-- SSDL content --> 2 <edmx:StorageModels> 3 <Schema Namespace="ASSModel.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/2006/04/edm/ssdl"> 4 <EntityContainer Name="ASSModelStoreContainer"> 5 <EntitySet Name="Assignments" EntityType="ASSModel.Store.Assignments" store:Type="Tables" Schema="dbo" /> 6 <!-- 省略7个EntitySet的定义 --> 7 </EntityContainer> 8 9 <!-- 以下省略7个EntityType的定义 --> 10 <EntityType Name="Assignments"> 11 <Key> 12 <PropertyRef Name="AssID" /> 13 </Key> 14 <Property Name="AssID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" /> 15 <Property Name="AssName" Type="nchar" Nullable="false" MaxLength="20" /> 16 <Property Name="AssDes" Type="nvarchar" MaxLength="500" /> 17 <Property Name="SCID" Type="int" Nullable="false" /> 18 <Property Name="Deadline" Type="datetime" Nullable="false" /> 19 <Property Name="QuesFileName" Type="nvarchar" MaxLength="500" /> 20 <Property Name="QuesFileUrl" Type="nvarchar" Nullable="false" MaxLength="500" /> 21 </EntityType> 22 23 <!-- 保留与CSDL中对应的Function --> 24 <Function Name="GETHOUSEWORKDONE" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo"> 25 <Parameter Name="StuID" Type="int" Mode="In" /> 26 <Parameter Name="ClassID" Type="int" Mode="In" /> 27 <Parameter Name="Semester" Type="varchar" Mode="In" /> 28 </Function> 29 </Schema> 30 </edmx:StorageModels>
看文档的结构,SSDL与CSDL很详细,只是其中EntityType等使用数据库的概念的描述。
这其中有一个需要稍微介绍节点,DefiningQuery,首先看一下其出现的位置:
EntityContainer |
||||
EntitySet |
||||
DefiningQuery |
通过查询定义一个SSDL的EntitySet |
|||
特定于存储的查询语句 |
DefiningQuery定义通过实体数据模型 (EDM) 内的客户端投影映射到数据存储视图的查询。此类映射是只读的。也就是说如果想要更新此类EntitySet,需要使用下文介绍存储过程时提到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当在实体类设计器中导入无主键的表时,会自动生成此类使用DefiningQuery定义的EntitySet,要式样Entity Framework提供的自动更新服务而不定义存储过程,需要给数据表添加一个适当的主键,删除DefiningQuery节点并更新数据模型。
EDM之MSL
这个文件即上面所述的CSDL与SSDL的对应,主要包括CSDL中属性与SSDL中列的对应。
1 <!-- C-S mapping content --> 2 <edmx:Mappings> 3 <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS"> 4 <EntityContainerMapping StorageEntityContainer="ASSModelStoreContainer" CdmEntityContainer="ASSEntities"> 5 <EntitySetMapping Name="Assignments"> 6 <EntityTypeMapping TypeName="IsTypeOf(ASSModel.Assignments)"> 7 <MappingFragment StoreEntitySet="Assignments"> 8 <ScalarProperty Name="QuesFileName" ColumnName="QuesFileName" /> 9 <ScalarProperty Name="AssDes" ColumnName="AssDes" /> 10 <ScalarProperty Name="AssID" ColumnName="AssID" /> 11 <ScalarProperty Name="AssName" ColumnName="AssName" /> 12 <ScalarProperty Name="Deadline" ColumnName="Deadline" /> 13 <ScalarProperty Name="QuesFileUrl" ColumnName="QuesFileUrl" /> 14 </MappingFragment> 15 </EntityTypeMapping> 16 </EntitySetMapping> 17 <!-- 省略EntitySetMapping若干 --> 18 19 <!-- 保留对应于CSDL与SSDL的FunctionImportMapping --> 20 <FunctionImportMapping FunctionImportName="GETHOUSEWORKDONE" FunctionName="ASSModel.Store.GETHOUSEWORKDONE" /> 21 22 <AssociationSetMapping Name="FK_UpAssignments_Assignments" TypeName="ASSModel.FK_UpAssignments_Assignments" StoreEntitySet="UpAssignments"> 23 <EndProperty Name="Assignments"> 24 <ScalarProperty Name="AssID" ColumnName="AssID" /> 25 </EndProperty> 26 <EndProperty Name="UpAssignments"> 27 <ScalarProperty Name="UpAssID" ColumnName="UpAssID" /> 28 </EndProperty> 29 </AssociationSetMapping> 30 <!-- 省略AssociationSetMapping若干 --> 31 </EntityContainerMapping> 32 </Mapping> 33 </edmx:Mappings>
如上代码所示,MSL的根节点为Mapping,其中可以包含多个EntityContainerMapping(上例只有一个),每一个EntityContainerMapping对应着两个分别来自CSDL与SSDL的EntityContainer。这个EntityContainerMapping就是描述这两个EntityContainer间的对应。下面再给出一段代码展示EntityContainerMapping的基本格式。
1 <EntityContainerMapping StorageEntityContainer="" CdmEntityContainer=""> 2 <EntitySetMapping> 3 <EntityTypeMapping> 4 <MappingFragment> 5 <ScalarProperty /> 6 </MappingFragment> 7 <ModificationFunctionMapping> 8 <InsertFunction /> 9 <DeleteFunction /> 10 <UpdateFunction /> 11 </ ModificationFunctionMapping> 12 </EntityTypeMapping> 13 </EntitySetMapping> 14 15 <AssociationSetMapping> 16 <EndProperty> 17 <ScalarProperty /> 18 </EndProperty> 19 </AssociationSetMapping> 20 21 <FunctionImportMapping /> 22 </EntityContainerMapping>
同上文,下面列出这些节点的属性
EntityContainerMapping |
||||||
StorageEntityContainer |
SSDL中的EntityContainer名称 |
|||||
CdmEntityContainer |
CSDL中的EntityContainer名称 |
|||||
EntitySetMapping |
EntityContainer中每个EntitySet的对应 |
|||||
Name |
EntitySetMapping的名称 |
|||||
EntityTypeMapping |
描述CSDL中EntityType与SSDL中EntityType的对应 |
|||||
Name |
EntityTypeMapping的名称 |
|||||
TypeName |
对应CSDL内Entity的名称 – 格式:IsTypeOf(<名称>) 注:这个类及其子类将共享此EntityTypeMapping |
|||||
MappingFragment |
描述属性及字段间的对应 |
|||||
StoreEntitySet |
SSDL中的EntitySet名称 (由于CSDL中一个EntitySet可以对应多个SSDL中的EntitySet) |
|||||
ScalarProperty |
属性与字段对应 |
|||||
Name |
CSDL中的属性名 |
|||||
ColumnName |
SSDL中的字段名称 |
|||||
Condition |
详见说明2 |
|||||
ColumnName |
列名 |
|||||
Value |
值 |
|||||
ModificationFunctionMapping |
CUD对应的存储过程 |
|||||
InsertFunction/ UpdateFunction / DeleteFunction |
||||||
FunctionName |
||||||
QueryView |
||||||
Entity SQL |
||||||
AssociationSetMapping |
描述CSDL中的AssociationSet与SSDL中的EntitySet的对应关系 |
|||||
Name |
AssociationSetMapping的名称 |
|||||
StoreEntitySet |
SSDL中EntitySet的名称 |
|||||
TypeName |
CSDL中AssociationSet的名称 |
|||||
EndProperty |
一个AssociationSetMapping中有两个EndProperty 分别对应CSDL中两个End Role |
|||||
Name |
EndProperty的名称 |
|||||
ScalarProperty |
关系属性对应 |
|||||
Name |
CSDL中的属性名 |
|||||
ColumnName |
SSDL中的字段名称 |
|||||
ModificationFunctionMapping |
C/D对应的存储过程 |
|||||
InsertFunction/ DeleteFunction |
||||||
FunctionName |
||||||
QueryView |
||||||
EntitySQL |
||||||
FunctionImportMapping |
用于描述CSDL与SSDL间函数及函数参数的对应(详见下文存储过程部分) |
说明1:以上表中很重要的一个属性是MappingFragment中的StoreEntitySet属性,就像这个属性的说明中所说,其描述了CSDL的Entity对应到的SSDL的Entity的名称。这是实现下文EDM映射方案中第二条将一个概念模型的实体映射到多个存储模型的实体的关键设置。
说明2:Contain这个元素及其属性的作用是,当多个概念模型实体映射到一个存储模型实体时,该元素的属性决定了在什么情况下一个概念模型实体映射到指定的存储模型实体。
说明3:QueryView 元素定义概念模型中的实体与存储模型中的实体之间的只读映射。使用根据存储模型计算的 Entity SQL 查询定义此查询视图映射,并以概念模型中的实体表达结果集。同DefiningQuery定义的查询。此映射也是只读的。就是说如果想要更新此类EntitySet,也需要使用下文介绍存储过程时提到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当多对多关联在存储模型中所映射到的实体表示关系架构中的链接表时,必须为此链接表在AssociationSetMapping 元素中定义一个QueryView元素。定义查询视图时,不能在 AssociactionSetMapping 元素上指定 StorageSetName 属性。定义查询视图时,AssociationSetMapping 元素不能同时包含 EndProperty 映射。
EDM中存储过程的设计
目前版本(VS2008SP1)的实体设计器对存储过程支持不完善,只能手工编辑这三个文件中的存储过程部分,包括:
- CSDL中的FunctionImport元素,其属性及说明如下所示:
FunctionImport
Name
(在程序中调用的)函数的名称
EntitySet
当函数返回实体对象时,需使用此属性指定对应的EntitySet
ReturnType
函数返回值的类型
Parameter
以下用于参数子节点中的属性定义
Name
参数的名称
Type
参数的类型
Mode
参数的传递方式(In, Out或InOut)
MaxLength
参数值最大长度
Precision
参数值的精确度,用于数字类型
Scale
浮点数小数位 - SSDL中的Function节
Function
Name
存储过程名称
Aggregate
是否为聚合函数(存储过程)
BuiltIn
是否为内建存储过程
NiladicFunction
是否为无参数存储过程
IsComposable
True为自定义函数,False为存储过程
ParameterTypeSemantics
参数类型转换方式
ReturnType
存储过程返回类型 - MSL中的FunctionImportMapping节
FunctionImportMapping
FunctionImportName
CSDL中FunctionImport的名称
FunctionName
SSDL中Function Element的名称这面总结的是用于返回实体对象的查询(存储过程)。
下面分别描述一下有关修改操作的存储过程的使用:
- 使用插入、更新或删除实体数据的存储过程,需要修改如下两个文件:
SSDL,对其的修改要求与上文表中列出的一致:MSL,需要对一下节点进行定义:
EntityContainerMapping |
|||||
EntitySetMapping |
EntityContainer中每个EntitySet的对应 |
||||
EntityTypeMapping |
描述CSDL中EntityType与SSDL中EntityType的对应 |
||||
ModificationFunctionMapping |
CUD对应的存储过程 |
||||
InsertFunction/ UpdateFunction / DeleteFunction |
|||||
FunctionName |
- 使用创建或删除在数据源中使用链接表实现的实体类型之间的多对多关系的存储过程需要修改如下两个文件:
SSDL,对其的修改要求与上文表中列出的一致:MSL,需要对一下节点进行定义:
EntityContainerMapping |
||||
AssociationSetMapping |
描述CSDL中的AssociationSet与SSDL中的EntitySet的对应关系 |
|||
ModificationFunctionMapping |
C/D对应的存储过程 |
|||
InsertFunction/ DeleteFunction |
||||
FunctionName |
EDM中ComplexType的设计
再谈Complex Type,上文大致介绍了复杂类型的概念及作用,现在开始看一下具体怎样实现。前文已经提到实现复杂类型关键是在CSDL与MSL,而与SSDL无关。
首先应该在CSDL中怎加这样一节,此节与 <EntityType></EntityType> 节同级,其结构如下:
1 <ComplexType> 2 <Property /> 3 </ComplexType>
节点及其属性含义如下:
ComplexType |
复杂类型 |
|
Name |
复杂类型的名称 |
|
Property |
属性 |
|
Name |
属性名 |
|
Type |
属性类型 |
|
Nullable |
是否允许null |
|
MaxLength |
属性最大长度 |
|
FixLength |
是否固定长度 |
然后在MSL中 <MappingFragment>下与<ScalarProperty /> 同级的位置添加如下节:
1 <ComplexProperty> 2 <ScalarProperty /> 3 </ComplexProperty>
具体的节及其属性含义如下:
ComplexProperty |
复杂类型属性 |
|
Name |
复杂类型属性名称 |
|
TypeName |
CSDL中定义的ComplexType的名称。格式"CSDN_Namespace.ComplexTypeName" |
|
ScalarProperty |
关系属性对应 |
|
Name |
CSDL中的属性名 |
|
ColumnName |
SSDL中的字段名称 |
实体数据模型映射方案
实体框架支持各种方式用于在实体数据模型 (EDM) 中将概念模型映射到关系数据。有关更多信息,请参见 实体框架中的数据建模。
实体框架当前支持以下实体数据模型 (EDM) 映射方案。
编号 |
映射方案 |
说明 |
1 |
简单映射 |
在此映射方案中,概念模型中的每个实体都映射到存储模型中的单个表。这是实体数据模型工具所生成的默认映射。 |
2 |
实体拆分 |
在此映射方案中,概念模型中单个实体的属性映射到两个或更多基础表中的列。在此方案中,表必须共享公共主键。 其设计方式见EDM之MSL部分说明1。 |
3 |
存储模型中的水平分区 |
在此映射方案中,概念模型中的单个实体类型映射到具有相同架构的两个或更多表。实体基于概念模型中定义的条件映射到表中。 使用场合:使一个概念模型的实体映射到不同数据源的存储模型的实体。 另见:EDM之MSL部分说明2。 |
4 |
概念模型中的水平分区 |
在此映射方案中,概念模型中具有相同属性的多个实体类型映射到同一个表。条件子句用于指定表中的数据分别属于哪个实体类型。此映射类似于类型5。 这种方式也用到MSL中的Conditon来决定映射关系,见EDM之MSL部分说明2。 |
5 |
每个层次结构一个表继承 |
在此映射方案中,继承层次结构中的所有类型都映射到同一个表。条件子句用于定义实体类型。 见EDM之MSL部分说明2。 |
6 |
每种类型一个表继承 |
在此映射方案中,所有类型都分别映射到各自的表。仅属于某个基类型或派生类型的属性存储在映射到该类型的一个表中。 |
7 |
每种具体类型一个表继承 |
在此映射方案中,每个非抽象类型分别映射到不同的表。所有这些表所包含的列必须映射到派生类型的所有属性(包括从基类型继承的属性)。 |
8 |
每种类型多个实体集 |
在此映射方案中,单个实体类型在概念模型中以两个或更多独立的实体集进行表示。每个实体集分别映射到存储模型中的一个单独的表。 其设计方式见EDM之MSL部分说明1。 |
9 |
复杂类型 |
复杂类型是没有键属性的实体类型的非标量属性。复杂类型可以包含其他嵌套的复杂类型。复杂类型映射到存储模型中的表。 复杂类型在上文有单独介绍 |
10 |
函数导入映射 |
在此方案中,存储模型中的存储过程映射到概念模型中的 FunctionImport 元素。执行此函数可使用映射的存储过程返回实体数据。 见上文存储过程部分 |
11 |
修改函数映射 |
在此方案中,在存储模型中定义用于插入、更新和删除数据的存储过程。这些函数是为实体类型定义的,以便为特定实体类型提供更新功能。 见上文存储过程部分 |
12 |
定义查询映射 |
在此方案中,在存储模型中定义表示数据源中的表的查询。在映射到 SQL Server 数据库时,查询以数据源的本机查询语言(如 Transact-SQL)表示。此 DefiningQuery 元素映射到概念模型中的实体类型。查询以特定于存储的查询语言进行定义。 上文EDM之SSDL部分最后详细介绍了这种设计的相关问题 |
13 |
查询视图映射 |
在此方案中,会在概念模型中的实体类型与存储模型中的关系表之间定义只读映射。此映射基于对存储模型进行的 Entity SQL 查询定义。 上文EDM之MSL中说明三对这种设计的相关问题有介绍。 |
14 |
AssociationSet 映射 |
关联定义实体之间的关系。在具有一对一或一对多关联的简单映射中,在概念模型中定义关系的关联会映射到存储模型中的关联。还支持以下更高级的关联集映射: 多对多关联。关联的两端都映射到存储模型中的链接表。 自关联。此映射支持具有相同类型的两个实体之间的关联,如一个 Employee 与另一个 Employee 之间的关联。 派生类型之间的关联。此映射支持一个层次结构中的派生类型与另一个层次结构中的派生类型之间的关联。 |