前言

Many to many 是 EF Core 5.0 才开始有的, 以前都用 2 个 1-n 来实现的.

由于它比 1-n 复杂, 所以有必要写一遍来记入一下.

参考:

Relationships

Property bag entity types

Without Fluent API

public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; } public ICollection<Tag> Tags { get; set; }
} public class Tag
{
public string TagId { get; set; } public ICollection<Post> Posts { get; set; }
}

在完全没有 Fluent API 配置下, 只要 2 个 class 有关系的 collection 就可以表达 n-n 了.

它会自动创建一个 Join entity type configuration, 就可以生产 migration 了.

为什么是 CategoryProduct 而不是 ProductCategory 呢?

它是按 class name A-Z 排序的. C 比 P 前面, 所以就是 CategoryProduct.

Joining relationships configuration (Dictionary)

想自己配置 Join entity type configuration 也是 ok 的.

modelBuilder.Entity<Category>()
.HasMany(e => e.Products)
.WithMany(e => e.Categories)
.UsingEntity<Dictionary<string, object>>(
j => j
.HasOne<Product>()
.WithMany()
.HasForeignKey("ProductId")
.OnDelete(DeleteBehavior.Cascade),
j => j
.HasOne<Category>()
.WithMany()
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade),
j =>
{
j.ToTable("CategoryProduct");
j.Property<int>("Id").HasColumnName("CategoryProductId");
j.HasKey("Id").IsClustered(false);
j.HasIndex("ProductId", "CategoryId").IsUnique().IsClustered(true); j.HasAnnotation("AuditTrail", null);
j.Property<string>("CreatedBy");
j.Property<DateTimeOffset>("DateCreated");
}
);

第 3 个 parameter 是配置 Join Entity. 注意这里用的是 Dictionary 来表示 Join Entity 而不是 class, 这个做法比较适合那种在 application level 不会用到这个 join entity 的情况.

如果需要用到的话, 那么应该用下面这个方式.

Joining relationships configuration (Class)

public class CategoryProduct
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; } = null!;
public int CategoryId { get; set; }
public Category Category { get; set; } = null!;
public string CreatedBy { get; set; } = "";
public DateTimeOffset DateCreated { get; set; }
}

没有太大的区别, 就是定义多一个 class 就 ok 了.

modelBuilder.Entity<Category>()
.HasMany(e => e.Products)
.WithMany(e => e.Categories)
.UsingEntity<CategoryProduct>(
j => j.HasOne(e => e.Product)
.WithMany()
.HasForeignKey(e => e.ProductId)
.OnDelete(DeleteBehavior.Cascade),
j => j.HasOne(e => e.Category)
.WithMany()
.HasForeignKey(e => e.CategoryId)
.OnDelete(DeleteBehavior.Cascade),
j =>
{
j.ToTable("CategoryProduct");
j.HasKey(e => e.Id).IsClustered(false);
j.HasIndex(e => new { e.CategoryId, e.ProductId }).IsUnique().IsClustered(true);
}
);

EF Core – Many to Many的更多相关文章

  1. EF Core 数据库迁移(Migration)

    工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用  Pomelo.EntityFrameworkCore.MySql   源代码地址(https://github. ...

  2. Asp.net Core 通过 Ef Core 访问、管理Mysql

    本文地址:http://www.cnblogs.com/likeli/p/5910524.html 环境 dotnet Core版本:1.0.0-preview2-003131 本文分为Window环 ...

  3. EF Core 杂记

    本系列文章,将介绍本人在学习和使用EF Core的过程中的收获与心得. 或许有的地方讲的错误 欢迎大家批评指出. 1.EF Core 数据库迁移(Migration)

  4. MySQL官方.NET Core驱动已出,支持EF Core

    千呼万唤始出来MySQL官方.NET Core驱动已出,支持EF Core. 昨天MySQL官方已经发布了.NET Core 驱动,目前还是预览版,不过功能已经可用. NuGet 地址:https:/ ...

  5. EF Core 1.0 和 SQLServer 2008 分页的问题

    EF Core 1.0 在sqlserver2008分页的时候需要指定用数字分页. EF Core1.0 生成的分页语句中使用了 Featch Next.这个语句只有在SqlServer2012的时候 ...

  6. EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...

  7. EF Core CodeFirst实践 ( 使用MS SqlServer)

    这里使用 MS SQLSERVER ,网上大多使用 SQLite 先来一个CodeFirst 新建项目 这里我们选择  ASP.NET Core Web Application (.NET Core) ...

  8. ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First

    ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...

  9. ASP.NET Core 开发 - Entity Framework (EF) Core

    EF Core 1.0 Database First http://www.cnblogs.com/linezero/p/EFCoreDBFirst.html ASP.NET Core 开发 - En ...

  10. 再谈EF Core内存数据库单元测试问题

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:在用EF Core的内存数据库进行单元测试的时候遇到"无法访问已释放的对象& ...

随机推荐

  1. Vue bug from backend

    一个后端引发前端的BUG 使用的框架是vue 代码里面有一个组件 <table :data="data"/> 获取后台数据 this.data = await fetc ...

  2. mysql:Windows修改MySQL数据库密码(修改或忘记密码)

    今天练习远程访问数据库时,为了方便访问,就想着把数据库密码改为统一的,以后我们也会经常遇到MySQL需要修改密码的情况,比如密码太简单.忘记密码等等.在这里我就借鉴其他人的方法总结几种修改MySQL密 ...

  3. Java JVM——12. 垃圾回收理论概述

    1.前言 1.1 什么是垃圾? 在提到什么是垃圾之前,我们先看下面一张图: 从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C++ 语言没有垃圾收集技 ...

  4. webpack4.15.1 学习笔记(八) — 缓存(Caching)

    目录 输出文件名(Output Filenames) 缓存第三方库 将 js 文件放到一个文件夹中 webpack 打包模块化后的应用程序,会生成一个可部署的 /dist目录,只要 /dist 目录中 ...

  5. 重写Save()的两种方法

    # 重新Save()def save(self, force_insert=False, force_update=False, using=None, update_fields=None): su ...

  6. [oeasy]python0022_框架标题的制作_banner_结尾字符串_end

    ​ 结尾字符串(end) 回忆上次内容 ​python3​​ 的程序是一个 5.3M 的可执行文件 ​​python3​​ 里面存的是 cpu 指令 可以执行的那种 我们可以把指令对应的汇编找到 ​​ ...

  7. Day 5 - 双指针与折半搜索

    双指针 本页面将简要介绍双指针. 引入 双指针是一种简单而又灵活的技巧和思想,单独使用可以轻松解决一些特定问题,和其他算法结合也能发挥多样的用处. 双指针顾名思义,就是同时使用两个指针,在序列.链表结 ...

  8. C# 对象复制三种方法效率对比——反射、序列化、表达式树

    1.需求 在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍. 比如: public class Student { public int Id { get; set; } publi ...

  9. 学习笔记--初识Java面向对象

    面向对象与面向过程的区别 面向过程:主要关注具体过程,因果关系 优点:对于业务逻辑比较简单的程序,可以得到快速开发,前期投入成本比较低 缺点:由于面向过程的使用让程序间的元素"耦合度&quo ...

  10. 分析C语言程序

    1 #include <stdio.h> 2 int main() 3 { 4 puts("C语言"); 5 return 0; 6 } 函数的概念 C语言提供了很多功 ...