[转]Entity Framework 的实体关系
通过 Entiy Framework实践系列 文章,理了理 Entity Framework 的实体关系。
为什么要写文章来理清这些关系?“血”的教训啊,刚开始使用 Entity Framework 的时候,由于没有静下心来认真理清关系,走了一些"痛不欲生"的弯路。而我们目前开发的项目都在使用 Entity Framework,为了避免其他人再经历"痛不欲生"的弯路。于是下定决心边“理清关系”边“写博客”。而写博客可以逼着自己把问题完整地解决,避免半 途而废。当写出这些文章,自己不知不觉对问题有了更深的理解。
温故而知新,通过这篇总结将自己对EF实体关系的理解回锅热一热,也许会有新的收获;感情也一样,当感情冷下来的时候,别忘了回锅热一热。

1. 一对一关系(one-to-one)
a) 单向一对一(文章链接)
类图:

数据库表结构:

Entity Framework中实体关系的定义:
modelBuilder.Entity<BlogSite>()
.HasRequired(b => b.BlogUser)
.WithMany()
.HasForeignKey(b => b.UserID);
b) 双向一对一(文章链接)
类图:

数据库表结构:

Entity Framework中实体关系的定义:

modelBuilder.Entity<BlogSite>()
.HasRequired(b => b.BlogUser)
.WithMany()
.HasForeignKey(b => b.UserID); modelBuilder.Entity<BlogUser>()
.HasRequired(u => u.BlogSite)
.WithMany()
.HasForeignKey(u => u.BlogID);

2. 一对多关系(one-to-many,文章链接)
类图:

数据库表结构:

Entity Framework中实体关系的定义:
modelBuilder.Entity<BlogSite>()
.HasMany(b => b.BlogPosts)
.WithRequired(p => p.BlogSite);
3. 多对多关系(many-to-many,文章链接)
类图:

数据库表结构:

Entity Framework中实体关系的定义:

modelBuilder.Entity<BlogPost>()
.HasMany(b => b.Categories)
.WithMany(c => c.BlogPosts)
.Map
(
m =>
{
m.MapLeftKey("BlogPostID");
m.MapRightKey("CategoryID");
m.ToTable("BlogPost_Category");
}
);

HasMany() = (1..*), HasOptional() = (1..0,1), HasRequired() = (1..1)
-------------------------------
在演示Fluent API如何配置Person类和PersonPhoto的一对一关系之前,先系统的学习下EF里实体关系配置的方法。EF里的实体关系配置分为Has和With系列的方法:Optional 可选的、Required 必须的、Many 多个。举例:
A.HasRequired(a => a.B).WithOptional(b => b.A);
这里的a=>a.B是lambda表示写法,就是找到A类里的导航属性B。命名a不固定,可以随意,q=>q.B也是可以的。但是B是A类的属性,故习惯用小写a。
Has方法:
- HasOptional:前者包含后者一个实例或者为null
- HasRequired:前者(A)包含后者(B)一个不为null的实例
- HasMany:前者包含后者实例的集合
With方法:
- WithOptional:后者(B)可以包含前者(A)一个实例或者null
- WithRequired:后者包含前者一个不为null的实例
- WithMany:后者包含前者实例的集合
摘自这里 这是较为好的理解方式。上面一句配置意思就是A类包含B类一个不为null的实例,B类包含A类一个实例,也可以不包含。最标准的一对一配置。ok,现在试着写下上面Person类和PersonPhoto类的一对一的关系如何配置:
this.HasRequired(p => p.PhotoOf).WithOptional(p => p.Photo);
再跑下程序,数据库就生成了,是一对一的关系。Person表可以没有对应的PersonPhoto表数据,但是PersonPhoto表每一条数据都必须对应一条Person表数据。意思就是人可以没有照片,但是有的照片必须属于某个人。关系配置是这样的效果,其实可以随便改,也可以配置成每个人都必须有对应的照片。把上面的WithOptional改成WithRequired,对应到数据库里就是null变成了not null。
数据库里可以可视化的设置不级联删除,Fluent API配置此外键关系时可以设置不级联删除:
this.HasMany(d => d.Lodgings).WithRequired(l => l.Destination)
.Map(l => l.MapKey("DestinationId")) //一对多并指定外键名
.WillCascadeOnDelete(false); // 关闭级联删除
再跑下程序,去看下数据库本外键自然就没了级联删除。
园友郭明锋提供了一个很好的建议:考虑到EF中的级联删除并不常用,所以可以在全局里关掉所有主外键关系的级联删除,如果需要可以打开某个主外键的级联删除。
@郭明锋:好文章,很久没有看到这么好的EF文章了,推荐
EF默认开启级联删除,确实是挺操蛋的设置,所以我的做法是在上下文的OnModelCreating方法中
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
移除这个默认约定,再在需要开启级联删除的FluentAPI关系映射中用. WillCascadeOnDelete(true) 单独开启
[转]Entity Framework 的实体关系的更多相关文章
- Entity Framework管理实体关系(二):管理一对二关系
在上一篇文章中,简单的介绍了使用Fluent API如何管理一对一的实体关系,在这篇文章中,接着介绍Fluent API如何管理一对多的实体关系. 要在数据库中配置一对多关系,我们可以依赖EF约定,还 ...
- Entity Framework管理实体关系(一):管理一对一关系
我们现在已经知道如何使用Code First来定义简单的领域类,并且如何使用DbContext类来执行数据库操作.现在我们来看下数据库理论中的多样性关系,我们会使用Code First来实现下面的几种 ...
- Entity Framework Code First关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- EF(Entity Framework)多对多关系下用LINQ实现"NOT IN"查询
这是今天在实际开发中遇到的一个问题,需求是查询未分类的博文列表(未加入任何分类的博文),之前是通过存储过程实现的,今天用EF实现了,在这篇博文中记录一下. 博文的实体类BlogPost是这样定义的: ...
- Entity Framework(实体框架 EF)
什么是Entity Framework呢(下面简称EF)? EF(实体框架)是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架.ORM(对象关系映射框架):指的是面向 ...
- Entity Framework Code First关系映射约定【l转发】
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework一对多关系添加数据的两种方式
当使用Entity Framework添加一对多关系数据的时候,通常先添加一的数据,然后再添加多的数据.类似这样: //添加一的数据 var category = new Category{Name= ...
- Entity Framework关联实体的三种加载方法
推荐文章 EF性能之关联加载 总结很好 一:介绍三种加载方式 Entity Framework作为一个优秀的ORM框架,它使得操作数据库就像操作内存中的数据一样,但是这种抽象是有性能代价的,故鱼和熊掌 ...
- [CareerCup] 15.6 Entity Relationship Diagram 实体关系图
15.6 Draw an entity-relationship diagram for a database with companies, people, and professionals (p ...
随机推荐
- MPU-6000 与 MPU-6050
VLOGIC 是什么呢?
- 深入理解 js为什么没有函数重载,如何实现函数重载?
我的新博客 http://www.suanliutudousi.com/2017/08/24/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3-js%E4%B8%BA%E4%B ...
- fastReport.net 初了解
delphi 中fastReport rmReport都很好用,转到.net了,第一想法也是这两个,好在这里有个fastReport; 这个安装呢 找个破解的 有个4.x版 安完建一个winForm ...
- 无LoadLibrary获取指定模块基址
实际上,这块可以写成汇编,然后做远程注入用 方法 1.通过fs:[30h]获取当前进程的_PEB结构 2.通过_PEB的Ldr成员获取_PEB_LDR_DATA结构 3.通过_PEB_LDR_DATA ...
- C# async await 举个栗子
首先,async 和 await 代表异步执行和等待. async是一个标记,告诉编译器,我可能是一个异步方法. await 代表等待,告诉编译器,这里等我返回结果. 下面,我们简单说一下. 一 , ...
- 【JZOJ6367】工厂(factory)
description 大神 wyp 开了家工厂,工厂有 n 个工人和 p 条流水线. 工厂的工人都是睡神,因此第 i 个工人只会在 si 至 ti 时刻才会工作. 每个工人都会被分派到一条流水线上, ...
- VS 解决方案 Xamarin 配置
需要额外安装 Mono 程序 工具->Xamarin->Android -> SDK路径 要和 你配置的ANDROID_SDK_ROOT 的路径一至如果没有 ANDROID_SDK ...
- JMeter 返回Json数据提取方法
JMeter中,对response返回JSON格式的数据进行处理,格式如下: { "code":2000, "message":"success&qu ...
- thinkphp cbd模式
ThinkPHP从3.0版本开始引入了全新的CBD(核心Core+行为Behavior+驱动Driver)架构模式,因为从底层开始,框架就采用核心+行为+驱动的架构体系,核心保留了最关键的部分,并在重 ...
- 期望dp——zoj3640
/* dp[i]表示力量为i时的期望 dp[i]=sum{tj}/n+sum{dp[i+cj]+1}/n //前一项是cj<i的和,后一项是cj>=i的和 初始状态dp[m] */ #in ...