entityframework学习笔记--004-无载荷与有载荷关系
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-无载荷与有载荷关系的更多相关文章
- 【pytorch】学习笔记(四)-搭建神经网络进行关系拟合
[pytorch学习笔记]-搭建神经网络进行关系拟合 学习自莫烦python 目标 1.创建一些围绕y=x^2+噪声这个函数的散点 2.用神经网络模型来建立一个可以代表他们关系的线条 建立数据集 im ...
- entityframework学习笔记--001
最近想重新好好学习一下entityframework,于是在院子里找到了一篇不错的博客.下面把学习的过程记录下来,方便以后复习. 学习过程参考大神的博客:http://www.cnblogs.com/ ...
- entityframework学习笔记--005-给code first一个正确的解释
在微软官方关于ef7的介绍中强调,ef7将舍弃database first.model first,只保留code first的使用.这引起了很多人的担忧,担忧源自对code first的错误理解.因 ...
- 【原】Java学习笔记004 - 运算符
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 运算符:对常量 或 ...
- EntityFramework学习笔记1--安装
1.新建项目 2.工具=>NuGet程序包管理器=>程序包管理控制器 3.PM> Install-Package EntityFramework 安装EF
- entityframework学习笔记--009-使用原生sql语句操作数据
1 使用原生SQL语句更新--Database.ExecuteSqlCommand 假设你有一张如图9-1所示的Payment数据库表. 图9-1 1.1 实体类型: public class Pay ...
- entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH
Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...
- entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT
Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...
- entityframework学习笔记--006-表拆分与实体拆分
1.1 拆分实体到多张表 假设你有如下表,如图6-1.Product表用于存储商品的字符类信息,ProductWebInfo用于存储商品的图片,两张表通过SKU关联.现在你想把两张表的信息整合到一个实 ...
随机推荐
- 获取bing.com的图片并在gnome3中设置自动切换
发现 bing.com 上的图片很好看,因此打算每天把 bing.com 的图片下载下来,用作桌面. 需要做的是两个部分,爬取图片到目录和设置目录图片为桌面背景并可以自动切换. 第一部分,下载图片,使 ...
- Spring学习记录(八)---Bean的生命周期
之前说过,在调用下面时,就创建了容器和对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml&quo ...
- 应用Web.Config配置网站
1.配置数据库连接 在ASP.NET中配置数据库连接的两种方式: appSettings和connectionStrings 命名空间: using System.Configuration; 1)a ...
- Minor【 PHP框架】2.第一个应用与请求的生命周期
框架Github地址:github.com/Orlion/Minor (如果觉得还不错给个star哦(^-^)V) 框架作者: Orlion 知乎:https://www.zhihu.com/peop ...
- es6学习笔记一数组(下)
entries() 方法: 概述: entries() 方法返回一个 Array Iterator(数组迭代) 对象,该对象包含数组中每一个索引的键值对. 示例: let arr = [&quo ...
- 使用VS Code开发ASP.NET 5 应用程序
本文简要地翻译了 https://code.visualstudio.com/Docs/runtimes/ASPnet5 并结合我的实践做了一些说明. 准备工作 1.安装VS Code https: ...
- iOS 使用xib后获取view的frame出错的问题
如果控制器使用xib做的,在viewDidLoad方法中获取的view.frame是不正确的 这根xib的加载有关, 可以把需要做的事情写在viewWillAppear中就能解决
- java 中多线程之间的通讯之生产者和消费者 (多个线程之间的通讯)
在真实开发 中关于多线程的通讯的问题用到下边的例子是比较多的 不同的地方时if 和while 的区别 如果只是两个线程之间的通讯,使用if是没有问题的. 但是在多个线程之间就会有问题 /* * 这个例 ...
- 千呼万唤始出来:Apache Spark2.0正式发布
我们很荣幸地宣布,自7月26日起Databricks开始提供Apache Spark 2.0的下载,这个版本是基于社区在过去两年的经验总结而成,不但加入了用户喜爱的功能,也修复了之前的痛点. 本文总结 ...
- ZOJ Problem Set - 1045 HangOver
#include <stdio.h> int main() { float c; int i; while(scanf("%f",&c)!=EOF&&a ...