​ 在EF6.0 中,多对多关系配置时,系统会自动生成第三张表,来将两张有互相约束关系的表联系起来,但是在EF Core2.0中,我们需要手动建立第三张表,比如说有两个模型Passage.cs和Category.cs,若想建立两者之间的多对多关系,我们就需要借助第三张表PassageCategory来实现:

  1. public class Passage
  2. {
  3. //文章编号
  4. [Key]
  5. public long PassageId { get; set; }
  6. //标题
  7. public string Title { get; set; }
  8. //描述
  9. public string Description { get; set; }
  10. //内容
  11. public string Content { get; set; }
  12. //发布时间
  13. public DateTime PublishTime { get; set; }
  14. //最后编辑时间
  15. public DateTime LastEditTime { get; set; }
  16. //文章分类(使用技术等)
  17. public virtual IList<PassageCategory> PassageCategories { get; set; }
  18. }
  1. public class Category
  2. {
  3. [Key]
  4. public int CategoryId { get; set; }
  5. [MaxLength(50)]
  6. public string CategoryName { get; set; }
  7. public virtual IList<PassageCategory> PassageCategories { get; set; }
  8. }

  1. public class PassageCategory
  2. {
  3. public int CategoryId { get; set; }
  4. public Category Category { get; set; }
  5. public long PassageId { get; set; }
  6. public Passage Passage { get; set; }
  7. }

然后添加 FluentAPI 配置,在配置多对多关系时,必须指定级联删除。

​ 先说一下EFCore的几种级联模式:

  • Cascade

    ​ 依赖的实体也一并被删除。这种级联行为只对被上下文跟踪到的实体有效。数据库里也需要设置相应的级联,确保没有被上下文跟踪到的数据也具备同样的行为。如果你通过EF来创建数据库,那么EF会为你设置好数据库的级联。

  • Restrict

    ​ 删除操作不会作用在依赖实体上,依赖实体保持不变。

  • SetNull

    ​ 依赖实体的外键被设为null。这种级联行为只对被上下文跟踪到的实体有效。数据库里也需要设置相应的级联,确保没有被上下文跟踪到的数据也具备同样的行为。如果你通过EF来创建数据库,那么EF会为你设置好数据库的级联。

  • ClientSetNull

    ​ EFCore2.0引入了一种叫作ClientSetNull的默认行为。它具有SetNull的语义,兼有Restrict的行为。从我们的经验来看,对于被跟踪的实体和数据库来说,它是最被期待也是最有用的一种行为。

​ 在为被跟踪的实体设置级联关系时,DeleteBehavior.Restrict已经成为历史。

​ 添加一个新类 PassageCategoryMap.cs 该类继承自 IEntityTypeConfiguration 接口

  1. public class PassageCategoryMap : IEntityTypeConfiguration<PassageCategory>
  2. {
  3. /// <summary>
  4. /// PassageCategories FluentAPI配置
  5. ///
  6. /// 添加复合主键、配置多对多关系
  7. /// </summary>
  8. /// <param name="builder"></param>
  9. public void Configure(EntityTypeBuilder<PassageCategory> builder)
  10. {
  11. //添加复合主键
  12. builder.HasKey(t => new { t.PassageId, t.CategoryId });
  13. ///<summary>
  14. ///
  15. /// 配置Passage与PassageCategories的一对多关系
  16. ///
  17. /// EFCore中,新增默认级联模式为ClientSetNull
  18. ///
  19. /// 依赖实体的外键会被设置为空,同时删除操作不会作用到依赖的实体上,依赖实体保持不变,同下
  20. ///
  21. /// </summary>
  22. //配置Passage与PassageCategories的一对多关系
  23. builder.HasOne(t => t.Passage).WithMany(p => p.PassageCategories).HasForeignKey(t => t.PassageId).OnDelete(DeleteBehavior.SetNull);
  24. //配置Category与PassageCategories的一对多关系
  25. builder.HasOne(t => t.Category).WithMany(p => p.PassageCategories).HasForeignKey(t => t.CategoryId).OnDelete(DeleteBehavior.SetNull);
  26. }
  27. }

​ 然后在 DbContext 类中,重写 OnModelCreating 方法添加 FluentAPI 配置

  1. protected override void OnModelCreating(ModelBuilder builder)
  2. {
  3. base.OnModelCreating(builder);
  4. //查找所有FluentAPI配置
  5. var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);
  6. //应用FluentAPI
  7. foreach(var type in typesToRegister)
  8. {
  9. //dynamic使C#具有弱语言的特性,在编译时不对类型进行检查
  10. dynamic configurationInstance = Activator.CreateInstance(type);
  11. builder.ApplyConfiguration(configurationInstance);
  12. }
  13. }

​ 然后添加数据迁移,更新数据库,就完成了多对多关系数据库的配置。

EntityFramework Core2.0 多对多关系配置的更多相关文章

  1. hibernate多对多关系配置

    一.创建用户,角色实体类. 一名用户可以有多个角色.一个角色可以对于多名用户. 用户实体类 public class User { private int uId; private String uN ...

  2. EntityFrameWork Code First 多对多关系处理

    场景2: 一个文章类别(Category)下含有多篇文章(Article),而文章也可能对应多个类别 Article和Category的代码更改如下: /// <summary> /// ...

  3. Hibernate 关系配置

    表之间关系 1. 一对多 一个部门有多个员工,一个员工只能属于某一个部门 一个班级有多个学生,一个学生只能属于一个班级 2. 多对多 一个老师教多个学生,一个学生可以被多个老师教 一个学生可以先择多门 ...

  4. EF Core反向导航属性解决多对一关系

    多对一是一种很常见的关系,例如:一个班级有一个学生集合属性,同时,班级有班长.语文课代表.数学课代表等单个学生属性,如果定义2个实体类,班级SchoolClass和学生Student,那么,班级Sch ...

  5. MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载

    一.myBatis对象关系映射(多对一关系.一对多关系) 1.多对一关系: ---例子:多个员工同属于一个部门. (1)myBatis发送 额外SQL: ■ 案例:员工表通过 dept_id 关联 部 ...

  6. EF里一对一、一对多、多对多关系的配置和级联删除

    本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个PersonPhoto类,表示用户照片类 /// < ...

  7. 多对多关系<EntityFramework6.0>

    无负载建立多对多关联的模型 原文中是Modeling a Many-to-Many Relationship with No Payload,虽然这么翻译也有点不准确,但是可以说明其目的,如下图所示, ...

  8. EF——一对一、一对多、多对多关系的配置和级联删除 04(转)

    EF里一对一.一对多.多对多关系的配置和级联删除   本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个P ...

  9. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

随机推荐

  1. 修改ASP.NET文件上传大小限制

    转自:http://www.hello-code.com/blog/asp.net/201603/5954.html 要点: 1.web.config中的<httpRuntime maxRequ ...

  2. 用java做操作系统内核:软盘读写

    在前两节,我们将一段代码通过软盘加载到了系统内存中,并指示cpu执行加入到内存的代码,事实上,操作系统内核加载也是这么做的.只不过我们加载的代码,最大只能512 byte, 一个操作系统内核,少说也要 ...

  3. 【Xmail】使用Xmail搭建局域网邮件服务器

    下载地址:  http://www.xmailserver.org/xmail-1.27.win32bin.zip,当前最新版本  1.27. 解压文件:xmail-1.27.win32bin.zip ...

  4. SpringMVC源码阅读:Controller中参数解析

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  5. vue里面computed的运用理解

    computed 计算属性,是用来声明式的描述一个值依赖了其它的值,当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM.这个功能非常强大,它可以让你的 ...

  6. Linux中Redis的安装

    一.下载redis redis官网地址:http://www.redis.io/ 下载地址:http://download.redis.io/releases/ redis中文文档地址:http:// ...

  7. val();html();.text()区别

    对于innerHTML 属性,几乎所有的元素都有innerHTML属性,它是一个字符串,用来设置或获取位于对象起始和结束标签内的HTML.(获取HTML当前标签的起始和结束里面的内容) 对于inner ...

  8. C# byte 和 char 转化

    C#  byte 和 char 可以认为是等价的.但是在文本显示的时候有差异.   c# 使用的是unicode字符集,应该和为ascii相互转换 只能转换到字符的unicode编码,或者由unico ...

  9. unity 中的协程

    //The coroutine will continue after all Update functionshave been calledon the next frame. ; //Conti ...

  10. [日常] 研究redis未授权访问漏洞利用过程

    前提:redis允许远程连接,不需要密码 1522057495.583846 [0 123.206.24.121:50084] "set" "dUHkp" &q ...