1.无载荷(with NO Payload)的多对多关系建模

在数据库中,存在通过一张链接表来关联两张表的情况。链接表仅包含连接两张表形成多对多关系的外键,你需要把这两张多对多关系的表导入到实体框架模型中。

1.1 假设我们有如下数据关系:

我们有三张表用来存储Album(专辑)、Artist(艺人)、LinkTable(专辑与艺人的关系表)。一张“专辑”可以有多个“艺人”,同时一个“艺人”也可以有多张专辑。

1.2 右键你的项目,使用entityframework的database first创建实体模型。注意把这三张表都选上,当点击“完成”之后,实体框架生成的视图如图4-1

图4-1

1.3 观察图4-1可以发现,Album与Artist之间的关系被映射成了一条多对多的直线,而当初选择的LinkTable表没有出现在视图中。这是因为LinkTable中没有标量属性,也就是说没有载荷。实体框架认为,LinkTable存在的意义就是表示Album与Artist之间的关系的,而上图足以表示他两的关系,所以LinkTable就没有存在的必要了。但是如果LinkTable中有标量属性,实体框架则会为他创建相应的模型,如下一节2.1。

1.4 对上述关系的插入与查询测试。输出如图4-2

 using (var context = new ef6recipesEntities())
{ // 添加一个拥有两张专辑的艺术家
var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
var album1 = new Album { AlbumName = "Drive" };
var album2 = new Album { AlbumName = "Live at Texas Stadium" };
artist.Albums.Add(album1);
artist.Albums.Add(album2);
context.Artists.Add(artist); //添加两个艺术家的专辑
var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
var album = new Album { AlbumName = "Honkytonk University" };
artist1.Albums.Add(album);
artist2.Albums.Add(album);
context.Artists.Add(artist1);
context.Artists.Add(artist2); context.SaveChanges();
} using (var context = new ef6recipesEntities())
{
Console.WriteLine("Artists and their albums...");
var artists = context.Artists;
foreach (var artist in artists)
{
Console.WriteLine("{0} {1}", artist.FirstName, artist.LastName);
foreach (var album in artist.Albums)
{
Console.WriteLine("\t{0}", album.AlbumName);
}
}
Console.WriteLine("\nAlbums and their artists...");
var albums = context.Albums;
foreach (var album in albums)
{
Console.WriteLine("{0}", album.AlbumName);
foreach (var artist in album.Artists)
{
Console.WriteLine("\t{0} {1}", artist.FirstName, artist.LastName);
}
}
}

图4-2

2 有载荷的多对多关系建模

在数据库中,存在通过一张链接表来关联两张表的情况。链接表除了包含连接两张表形成多对多关系的外键外,还包含一些额外的属性,你需要把这两张多对多关系的表导入到实体框架模型中。

2.1 假设我们有如下关系:

一个订单(Order)可以拥有多个订单项(Item),一个订单项(Item)可以属于多个订单(Order),在连接Order、Item实例的关系上有一个Count属性,这个属性被称为一个有效载荷。

2.2 和上节的一样,右键你的项目,使用entityframework的database first创建实体模型。注意把这三张表都选上,当点击“完成”之后,实体框架生成的视图如图4-2-1

图4-2-1

2.3 观察上图可以发现与上节生成的视图有些不同。这次生成的视图好像更符合数据库中标的结构一样。Order与Item之间的多对多关系,被映射成两个一对多的关系,即Order与OrderItem的一对多、Item与OrderItem的一对多。

2.4 对上述关系的插入与查询测试。输出如图4-2-2

 using (var context = new ef6recipesEntities1())
{
var order = new Order
{
OrderId = ,
OrderDate = new DateTime(, , )
};
var item = new Item
{
SKU = ,
Description = "Backpack",
Price = 29.97
};
var oi1 = new OrderItem { Order = order, Item = item, Count = };
item = new Item
{
SKU = ,
Description = "Water Filter",
Price = 13.97
};
var oi2 = new OrderItem { Order = order, Item = item, Count = };
item = new Item
{
SKU = ,
Description = "Camp Stove",
Price = 43.99
};
var oi3 = new OrderItem { Order = order, Item = item, Count = };
context.OrderItems.Add(oi1);
context.OrderItems.Add(oi2);
context.OrderItems.Add(oi3);
context.SaveChanges();
} using (var context = new ef6recipesEntities1())
{
foreach (var order in context.Orders)
{
Console.WriteLine("Order # {0}, ordered on {1}",
order.OrderId.ToString(),
order.OrderDate.ToShortDateString());
Console.WriteLine("SKU\tDescription\tQty\tPrice");
Console.WriteLine("---\t-----------\t---\t-----");
foreach (var oi in order.OrderItems)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}", oi.Item.SKU,
oi.Item.Description, oi.Count.ToString(),
oi.Item.Price.ToString("C"));
}
}
}

图4-2-2

最后,虽然ef支持无载荷模式,但是在项目中最好不要使用,因为一旦以后要把无载荷改成有载荷模式,实体关系也要随之改变、程序代码也要随之改变,这样造成很多不必要的麻烦。有一个好的解决办法是,在项目的一开始就使用有载荷模式,即使我们的表在一开始是无载荷,我们也可以给他加一个随机的属性,使之变成有载荷模式。

entityframework学习笔记--004-无载荷与有载荷关系的更多相关文章

  1. 【pytorch】学习笔记(四)-搭建神经网络进行关系拟合

    [pytorch学习笔记]-搭建神经网络进行关系拟合 学习自莫烦python 目标 1.创建一些围绕y=x^2+噪声这个函数的散点 2.用神经网络模型来建立一个可以代表他们关系的线条 建立数据集 im ...

  2. entityframework学习笔记--001

    最近想重新好好学习一下entityframework,于是在院子里找到了一篇不错的博客.下面把学习的过程记录下来,方便以后复习. 学习过程参考大神的博客:http://www.cnblogs.com/ ...

  3. entityframework学习笔记--005-给code first一个正确的解释

    在微软官方关于ef7的介绍中强调,ef7将舍弃database first.model first,只保留code first的使用.这引起了很多人的担忧,担忧源自对code first的错误理解.因 ...

  4. 【原】Java学习笔记004 - 运算符

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 运算符:对常量 或 ...

  5. EntityFramework学习笔记1--安装

    1.新建项目 2.工具=>NuGet程序包管理器=>程序包管理控制器 3.PM> Install-Package EntityFramework 安装EF

  6. entityframework学习笔记--009-使用原生sql语句操作数据

    1 使用原生SQL语句更新--Database.ExecuteSqlCommand 假设你有一张如图9-1所示的Payment数据库表. 图9-1 1.1 实体类型: public class Pay ...

  7. entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH

    Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...

  8. entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT

    Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...

  9. entityframework学习笔记--006-表拆分与实体拆分

    1.1 拆分实体到多张表 假设你有如下表,如图6-1.Product表用于存储商品的字符类信息,ProductWebInfo用于存储商品的图片,两张表通过SKU关联.现在你想把两张表的信息整合到一个实 ...

随机推荐

  1. LINUX 下安装一些东西,PHP Apach SSL 等

    首先下载apache sourcecode:http://www.apache.org/dyn/closer.cgi configure: error: Cannot find ldap librar ...

  2. Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结

    Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结 1. Sql语言应该得到更大的范围的应用,1 1.1. 在小型系统项目中,很适合存储过程写业务逻辑2 1.2. 大型 ...

  3. python的shutil模块

    shutil模块提供了大量的文件的高级操作.特别针对文件拷贝和删除,主要功能为目录和文件操作以及压缩操作 1.复制文件 def copy(src, dst): """Co ...

  4. MongoDB 数据分发

    在MongoDB(版本 3.2.9)中,数据的分发是指将collection的数据拆分成块(chunk),分布到不同的分片(shard)上,数据分发主要有2种方式:基于数据块(chunk)数量的均衡分 ...

  5. Atom支持Markdown和Latex

    本篇博客主要用于记录Atom编辑器同时支持markdown和latex: 1.安装 安装方法1: (Windows系统)File->Settings->Install中搜索markdown ...

  6. 深入学习jQuery选择器系列第八篇——过滤选择器之伪子元素选择器

    × 目录 [1]通用形式 [2]反向形式 [3]首尾元素 [4]唯一元素 前面的话 本文是子元素选择器的续篇,主要介绍关于nth-of-type()选择器的内容.该部分内容并非没有出现在<锋利的 ...

  7. 解决在配置Oracle数据库连接错误问题

    项目开发使用的Oracle,但是使用了不同的版本的Oracle数据库.然后自己在电脑上安装了2个连接客户端,版本分别是: 10.2.0 12.1.0 用Toad for Oracle 9.0的时候,我 ...

  8. Util应用程序框架公共操作类(六):验证扩展

    前面介绍了仓储的基本操作,下面准备开始扩展查询,在扩展查询之前,首先要增加两个公共操作类,一个是经常要用到的验证方法,另一个是Lambda表达式的操作类. 很多时候,我们会判断一个对象是否为null, ...

  9. Util应用程序框架公共操作类(五):异常公共操作类

    任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public boo ...

  10. Oracel_子查询

    SQL子查询 子查询语法 SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table) 子查询 ( ...