举例说明EF CORE中模型之间的一对多、多对多关系的实现
该例子是我临时想出来的,不具有任何的实际意义。类图如图1所示。

图1
类代码:

[Table("student")]
public class Student
{
public int id { get; set; }
public string name { get; set; }
public int grade_id { get; set; }
public int address_id { get; set; }
[NotMapped]
public Address address { get; set; }
[NotMapped]
public List<Subject> subjects { get; set; }
[NotMapped]
public List<Teacher> teachers { get; set; }
}
Student

[Table("teacher")]
public class Teacher
{
public int id { get; set; }
public string name { get; set; }
public int subject_id { get; set; }
public int depart_id { get; set; }
public int address_id { get; set; }
[NotMapped]
public Address address { get; set; }
[NotMapped]
public List<Student> students { get; set; }
}
Teacher

[Table("grade")]
public class Grade
{
public int id { get; set; }
public string name { get; set; }
public int depart_id { get; set; }
[NotMapped]
public List<Student> students { get; set; }
}
Grade

[Table("subject")]
public class Subject
{
public int id { get; set; }
public string name { get; set; }
public int depart_id { get; set; }
[NotMapped]
public List<Teacher> teachers { get; set; }
[NotMapped]
public List<Student> students { get; set; }
}
Subject

[Table("depart")]
public class Department
{
public int id { get; set; }
public string name { get; set; }
[NotMapped]
public List<Address> addresses { get; set; }
[NotMapped]
public List<Grade> grades { get; set; }
[NotMapped]
public List<Subject> subjects { get; set; }
[NotMapped]
public List<Teacher> teachers { get; set; }
}
Department

[Table("address")]
public class Address
{
public int id { get; set; }
public string country { get; set; }
public string city { get; set; }
[NotMapped]
public List<Department> departs { get; set; }
}
Address
类之间的关系如表1描述。
表1

Department与Grade, Subject, Teacher之间都是一对多的关系。以Teacher为例,Department与Teacher之间的对应关系是通过depart_id外键实现的,那么在构建Department模型时,该关系用代码描述为:
builder.Entity<Department>()
.HasMany(d => d.teachers)
.WithOne(t => t.depart).HasForeignKey(t => t.depart_id);
其中t=>t.depart可以省略,即
builder.Entity<Department>()
.HasMany(d => d.teachers)
.WithOne().HasForeignKey(t => t.depart_id);
Department与Address之间是多对多的关系,这种关系映射在数据库时通常需要有一张关系表,用于记录Department和Address之间的关系。同样地,要给这张关系表也建立一个相应的类:
[Table("depart_address")]
public class Depart_Address
{
public int id { get; set; }
public int depart_id { get; set; }
public int address_id { get; set; }
[NotMapped]
public Department depart { get; set; }
[NotMapped]
public Address address { get; set; }
}
多对多的关系模型描述如下:
builder.Entity<Department>()
.HasMany(d => d.addresses)
.WithMany(a => a.departs)
.UsingEntity<Depart_Address>(
j => j.HasOne(pt => pt.address)
.WithMany().HasForeignKey(pt => pt.address_id),
j => j.HasOne(pt => pt.depart)
.WithMany().HasForeignKey(pt => pt.depart_id),
j => j.HasKey(t => new { t.depart_id, t.address_id }));
整段模型代码为:

protected override void OnModelCreating(ModelBuilder builder)
{
#region Student Relationships
// students-teachers : multi-to-multi
builder.Entity<Student>()
.HasMany(s => s.teachers)
.WithMany(t => t.students)
.UsingEntity<StudentTeacher>(
j => j.HasOne(pt => pt.teacher)
.WithMany()
.HasForeignKey(pt => pt.teacher_id),
j => j.HasOne(pt => pt.student)
.WithMany()
.HasForeignKey(pt => pt.student_id),
j => j.HasKey(t => new { t.student_id, t.teacher_id })); // students-subjects: multi-to-multi
builder.Entity<Student>()
.HasMany(s => s.subjects)
.WithMany(su => su.students)
.UsingEntity<StudentSubject>(
j => j.HasOne(pt => pt.subject)
.WithMany()
.HasForeignKey(pt => pt.subject_id),
j => j.HasOne(pt => pt.student)
.WithMany()
.HasForeignKey(pt => pt.student_id),
j => j.HasKey(t => new { t.student_id, t.subject_id })); // student-address: multi-to-one
builder.Entity<Student>()
.HasOne(s => s.address)
.WithMany()
.HasForeignKey(s => s.address_id);
#endregion #region Teacher Relationships
// teachers-address: multi-to-one
builder.Entity<Teacher>()
.HasOne(t => t.address)
.WithMany()
.HasForeignKey(t => t.address_id); builder.Entity<Teacher>()
.HasMany(t => t.students)
.WithMany(s => s.teachers)
.UsingEntity<StudentTeacher>(
j => j.HasOne(pt => pt.student)
.WithMany().HasForeignKey(pt => pt.student_id),
j => j.HasOne(pt => pt.teacher)
.WithMany().HasForeignKey(pt => pt.teacher_id),
j => j.HasKey(t => new { t.teacher_id, t.student_id }));
#endregion #region Department Relationships
// department-grades: one-to-multi
builder.Entity<Department>()
.HasMany(d => d.grades)
.WithOne().HasForeignKey(g => g.depart_id); // department-teachers: one-to-multi
builder.Entity<Department>()
.HasMany(d => d.teachers)
.WithOne().HasForeignKey(t => t.depart_id); // department-subjects: one-to-multi
builder.Entity<Department>()
.HasMany(d => d.subjects)
.WithOne().HasForeignKey(s => s.depart_id); // departments-addresses: multi-to-multi
builder.Entity<Department>()
.HasMany(d => d.addresses)
.WithMany(a => a.departs)
.UsingEntity<Depart_Address>(
j => j.HasOne(pt => pt.address)
.WithMany().HasForeignKey(pt => pt.address_id),
j => j.HasOne(pt => pt.depart)
.WithMany().HasForeignKey(pt => pt.depart_id),
j => j.HasKey(t => new { t.depart_id, t.address_id }));
#endregion #region Grade Relationships
// grade-students: one-to-multi
builder.Entity<Grade>()
.HasMany(g => g.students)
.WithOne().HasForeignKey(s => s.grade_id);
#endregion #region Subject Relationships
// subjects-students: multi-to-multi
builder.Entity<Subject>()
.HasMany(s => s.students)
.WithMany(stu => stu.subjects)
.UsingEntity<StudentSubject>(
j => j.HasOne(pt => pt.student)
.WithMany()
.HasForeignKey(pt => pt.student_id),
j => j.HasOne(pt => pt.subject)
.WithMany()
.HasForeignKey(pt => pt.subject_id),
j => j.HasKey(t => new { t.subject_id, t.student_id })); builder.Entity<Subject>()
.HasMany(s => s.teachers)
.WithOne().HasForeignKey(t => t.subject_id);
#endregion
}
OnModelCreating
测试:
1.构建Department对象
Department depart = context.departs
.Include(d => d.subjects)
.ThenInclude(s=>s.students)
.ThenInclude(s=>s.teachers)
.Include(d=>d.addresses)
.Include(d => d.teachers)
.ThenInclude(t=>t.students)
.Include(d => d.grades)
.ThenInclude(g => g.students).First();

Console.WriteLine("department name: " + depart.name);
Console.WriteLine();
Console.WriteLine("department subjects:");
foreach(var item in depart.subjects)
{
Console.WriteLine((depart.subjects.IndexOf(item)+1).ToString()+"." + item.name);
Console.WriteLine("Students choose this subject:");
foreach (var stu in item.students)
Console.Write(stu.name+",");
Console.WriteLine();
Console.WriteLine("Teachers who teach this subject:");
foreach (var t in item.teachers)
Console.Write(t.name+",");
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("department teachers:");
foreach(var item in depart.teachers)
{
Console.WriteLine((depart.teachers.IndexOf(item)+1).ToString()+"."+item.name);
Console.WriteLine("his or her students:");
foreach (var stu in item.students)
Console.Write(stu.name + ",");
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("department grades:");
foreach(var item in depart.grades)
{
Console.WriteLine((depart.grades.IndexOf(item) + 1).ToString() + "." + item.name);
Console.WriteLine("students in this grade:");
foreach (var stu in item.students)
Console.Write(stu.name + ",");
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("department addresses:");
foreach(var item in depart.addresses)
{
Console.WriteLine(item.country + "." + item.city);
}
Test depart
测试结果:

2.构建Students对象
List<Student> students = context.students
.Include(s => s.subjects)
.Include(s => s.teachers)
.Include(s => s.address).ToList();

Console.WriteLine("Students List:");
foreach(var item in students)
{
Console.WriteLine((students.IndexOf(item) + 1).ToString() + "." + item.name);
Console.WriteLine("his or her subjects:");
foreach(var sub in item.subjects)
{
Console.Write(sub.name + ",");
}
Console.WriteLine();
Console.WriteLine("his or her teachers:");
foreach (var t in item.teachers)
Console.Write(t.name + ",");
Console.WriteLine();
Console.WriteLine("his or her address:" + item.address.country + "." + item.address.city);
}
Test students

完整代码路径:
https://github.com/Larissa1990/EFcore_demo
举例说明EF CORE中模型之间的一对多、多对多关系的实现的更多相关文章
- EF Core中通过Fluent API完成对表的配置
EF Core中通过Fluent API完成对表的配置 设置实体在数据库中的表名 通过ToTable可以为数据模型在数据库中自定义表名,如果不配置,则表名为模型名的复数形式 public class ...
- EF Core中避免贫血模型的三种行之有效的方法(翻译)
Paul Hiles: 3 ways to avoid an anemic domain model in EF Core 1.引言 在使用ORM中(比如Entity Framework)贫血领域模型 ...
- EF Core中如何正确地设置两张表之间的关联关系
数据库 假设现在我们在SQL Server数据库中有下面两张表: Person表,代表的是一个人: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ...
- [小技巧]EF Core中如何获取上下文中操作过的实体
原文地址:https://www.cnblogs.com/lwqlun/p/10576443.html 作者:Lamond Lu 源代码:https://github.com/lamondlu/EFC ...
- EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery
一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文 ...
- EF Core 中多次从数据库查询实体数据,DbContext跟踪实体的情况
使用EF Core时,如果多次从数据库中查询一个表的同一行数据,DbContext中跟踪(track)的实体到底有几个呢?我们下面就分情况讨论下. 数据库 首先我们的数据库中有一个Person表,其建 ...
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
项目开发中的一些注意事项以及技巧总结 1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...
- 第五节:EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope)
一. 说明 EF版本的事务介绍详见: 第七节: EF的三种事务的应用场景和各自注意的问题(SaveChanges.DBContextTransaction.TransactionScope). 本节主 ...
- EF Core 配置模型
0 前言 本文的第一节,会概述配置模型的作用(对数据模型的补充描述). 第二节描述两种配置方式,即:数据注释(data annotations)和 Fluent API 方式. 第三节开始,主要是将常 ...
随机推荐
- CAS基础
有锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一 ...
- es6中的导入与导出
参考:https://www.cnblogs.com/sherrycat/p/11152994.html
- gin中绑定查询字符串或表单数据
package main import ( "github.com/gin-gonic/gin" "log" "time" ) type P ...
- 微信 CLI 工具正式发布 v1.0
前言 为了让开发者可以更加方便舒适地获取到微信开发的资源,今天我们基于 Senparc.Weixin SDK 正式发布了基于 .NET 的微信 CLI 工具:Weixin.CLI(v1.0). 通过 ...
- 【第十三期】B站后端开发实习生一、二面经
写在最前:非科班渣硕去年转码一年,不是什么大佬,纯小白(go语言开发). 一面(大概70min) 首先是自我介绍.(比较传统,就是描述下自己的技术栈) 线程和进程的关系. 线程之间如何进行通信. 死锁 ...
- FTP工具安装
开放ftp端口,开房ftp服务即可 firewall-cmd --add-service=ftp --permanent firewall-cmd --reload
- Eclipse 堆栈和内存大小设置(转载)
1, 设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs //虚拟机设置 -Xms40m -Xmx256m -XX:PermSize=128M ...
- 使用rsync+inotify实现/www目录实时同步
一.实现bak-server 1.1安装rsync # yum -y install rsync 1.2修改配置文件 # vi /etc/rsyncd.conf #添加下面内容 uid=test gi ...
- linux_3
1.统计出/etc/passwd文件中其默认shell为非/sbin/nologin的用户个数,并将用户都显示出来 [root@lhq ~]#echo "total:`cat /etc/pa ...
- x86架构中的外部中断结构-Part 1:中断控制器的演化
本文主要讲解了x86体系架构从外部设备接受中断的过程,本文是系列文章的第一部分,试图回答以下问题: 什么是PIC以及它的用途是什么? 什么是APIC以及它的用途是什么?LAPIC和I/O APIC的目 ...