博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework 4 in Action读书笔记——第五章:域模型映射(Domain model mapping)(二)...
阅读量:5862 次
发布时间:2019-06-19

本文共 5143 字,大约阅读时间需要 17 分钟。

在模型中定义关系

在OrderIT模型中,有三种类型的关联:one-to-one,one-to-many和many-to-many。

One-to-one 关系

one-to-one关系的典型例子是订单详细(order detail)和订单(order)。创建这种类型的关联一点也不困难,但是涉及几个步骤:

1. 通过添加导航属性修改OrderDetail类。如果选择外键关联,还必须加上外键属性。

2. 修改CSDL将属性添加到类描述并引入关系。
3. 修改存储模式(storage schema)引入表之间的外键(如果存在)。
4. 修改映射模式(mapping schema)映射关系(只对独立关联)。

下面让我们看一下每个步骤。

修改类

创建从order detail到order的引用,需要在OrderDetail类中创建一个Order属性。因为使用了外键,还必须添加一个外键属性,如下面的清单所示:

创建order detail引用order的属性
public class OrderDetail{    public virtual int OrderDetailId { get; set; }    public virtual int Quantity { get; set; }    public virtual decimal Price { get; set; }    public virtual decimal Discount { get; set; }    //导航属性    public virtual Order Order { get; set; }    //外键属性    public virtual int OrderId { get; set; }}

在代码中的工作就这些。

修改概念模式(conceptual schema)

导航属性使用NavigationProperty元素添加到Name为OrderDetail的EntityType节点。Name特性映射元素为对象中属性,Relationship需要关系的完整名称,FromRole指定起点,ToRole指定结束点。外键属性使用Property。(书中有误)

在CSDL中为实体添加导航和外键属性

对实体的描述就这些。下面看一下关系描述。

在EntityContainer元素中,需要为每一个关联声明AssociationSet。它有两个特性:

  1. Name——关系集的名称。
  2. Association——指定类型。

在AssociationSet内,插入两个End节点,Role特性的值为类的名称,EntitySet的值为实体集的名称。

在EntityContainer外部,需要使用Association元素描述关系。它的Name属性链接到AssociationSet的描述,而内嵌的End元素描述关系的类型和它们的基数。在End元素中重要的就是Multiplicity特性,它有下面可选值:

1

0..1
*

End允许指定删除级联行为。这与数据库无关,只是父实体标记为删除时,子实体也被标记了。

声明和定义关联

在本例中,Order是为1的一方,OrderDetail是为*的一方,也就是说映射的是one-to-many关系!one-to-many关系也隐式声明了one-to-one关系。一个订单有多个详细,但是一个详细只对应一个订单。

独立关联(independent association)在MSL中映射,但是外键关联(foreign-key association)在CSDL中映射。因为在本例中已经选择了外键关联,必须将映射信息添加到关联定义中。这个信息添加到Association元素内的ReferentialConstraint节点,在End节点后面。

定义外键关联

ReferentialConstraint仅仅是个容器元素。映射真正发生在Principal和Dependent节点,在这里面可以定义主类(master class)的主键和在从类(child class)的外键属性。

概念模式完成了,下面修改存储模式。

修改存储模式(storage schema)

在存储模式中描述关系和概念模式中类似。在实体容器(entity container)中声明关系,然后在它外边描述。

直接看代码吧。

在存储模式中定义数据库外键约束

修改映射模式(mapping schema)

映射模式并不知道外键关联。但它只需要知道外键属性是如何映射到数据库中的外键

在本例中,将OrderDetail类的OrderId属性映射到OrderDetail表的OrderId列,代码如下:

订单和订单详细之间的one-to-one关系就完成了,下面看看如何建立两者的one-to-many关系。

One-to-many 关系

创建one-to-many关系跟创建one-to-one关系仅仅有一点不同。过程跟之前的完全相同,但是因为已经在EDM中添加了关联,你只需修改Order类并在CSDL中反应修改。

给父类(parent class)添加属性

Order类使用名为OrderDetails的集合属性引用它的详细。该属性必须是ICollection<OrderDetail>,ISet<OrderDetail>,或者任何实现了它们的类型,如List<T>或者HashSet<T>。

集合属性在范围是需要被初始化,否则会得到NullReferenceException。如何创建属性要根据你选择的集合类型。如果使用接口,则延迟实例化。如果使用的是真实类型,则可以在构造函数中也可以延迟实例化。

建议始终使用延迟实例化的方法,如下面的清单:

创建引用对象集合的属性
public class Order{    private ICollection
_OrderDetails; public ICollection
OrderDetails { get { _OrderDetails = _OrderDetails ?? new HashSet
(); return _OrderDetails; } set { _OrderDetails = value; } }}

修改概念模式(conceptual schema)

在概念模式中给Order描述添加新的属性,跟在OrderDetail中一样,添加一个NavigationProperty,修改Name特性并将Roles反过来,因为这里是从Order到OrderDetail。

就这些。关系已经在CSDL和SSDL中定义了;在MSL没有地方需要修改,因为导航属性不需要映射。

下一个需要分析的关系是many-to-many。在OrderIT中,这种关系存在于products和suppliers。

Many-to-many 关系

创建many-to-many的步骤也是一样的。首先,创建两个类的集合属性关联彼此,然后修改EDM。这种类型关系的不同之处是没有外键属性。类之间是直接的关系,所以数据库中的连接表在模型中没有与之对应的。这就意味着必须使用独立关联(independent association)。

到目前为止,已经看到了类,CSDL和SSDL的相关代码。下面快速回顾一下如何在product和supplie间建立多对多的关系:

1. Product和Supplier需要使用集合属性关联彼此。

2. 在CSDL中,需要映射类和它们的关联,不需要插入外键关联的信息。
3. 在SSDL中,需要声明和定义Product,Company和ProductSupplier表和它们的关联。
4. 在MSL中,需要映射Product和Supplier之间的关系到数据库。

在这一点上,因为没有使用外键关联,必须定义如何关联类,这个工作在映射文件中完成。

修改映射模式(mapping schema)

在映射模式中,使用AssociationSetMapping元素映射数据库列到独立关联(independent association)。AssociationSetMapping元素有三个特性:

1. Name——指定概念模式中的关联名。

2. TypeName——表示概念模式中的关联集(association set)的全名。
3. StoreEntitySet——包含数据库中子表的名称。

在AssociationSetMapping内部,放置两个EndProperty元素,它们的Name特性匹配概念模式中Association节点End元素的Role特性。最后,包含进一个ScalarProperty元素,指定类的属性和连接表的外键列。

映射独立(Independent)属性

结束了!many-to-many关系仅仅需要在映射模式中一个新的标签。在讨论继承之前,先来看看下面的内容。

关于关系的一些Tips

关于关系,首先要知道的是不是必须使用外键关联。例如,可以从OrderDetail中移除OrderId,使用独立关联和Order映射关联。但是使用外键关联比使用独立关联简单,尤其当你存储一个对象图时更是这样。如果可能,我们始终推荐使用外键。

另一件你需要知道的是不能同时使用外键关联和独立关联。你必须选择其中之一使用,设计器强制实施此规则,如果两个同时使用,它则会禁用一个。

如果你不想在many-to-many中使用独立关联,可以遵循LINQ to SQL方法:创建一个类,匹配连接表,然后再将类和表关联。这允许使用外键,但这是很差的设计,我们不建议这样。

下一篇将学习映射继承。

转载于:https://www.cnblogs.com/nianming/archive/2011/10/28/2227699.html

你可能感兴趣的文章
Openstack 安装部署指南翻译系列 之 Glance服务安装(Image)
查看>>
MongoDB基础操作
查看>>
MS SQL SERVER搜索某个表的主键所在的列名
查看>>
用 datalist控件进行分页(28)
查看>>
槽函数中显示对话框一闪而过
查看>>
easyUI 中datagrid 返回列隐藏方法
查看>>
使用expect编写脚本
查看>>
del_timer_sync不能睡眠的原因
查看>>
BIOS的自检原理和其重要性
查看>>
Python 字符串操作方法大全
查看>>
linux 修改时区 改为24小时制
查看>>
Docker镜像的构建
查看>>
移动硬盘上安装win8
查看>>
如何接管SBO系统的内置业务流程
查看>>
Backtrack5 SQL注入漏洞探测
查看>>
[UWP]了解模板化控件(5.1):TemplatePart vs. VisualState
查看>>
vSphere HA
查看>>
揭开.NET 2.0配置之谜(三)
查看>>
安装及管理程序
查看>>
云主机迁移脚本
查看>>