举例说明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 方式. 第三节开始,主要是将常 ...
随机推荐
- Python中的路径
转义 windows路径使用的是\,linux路径使用的是/. 特别的,在windows系统中如果有这样的一个路径 D:\nxxx\txxx\x1,程序会报错.因为在路径中存在特殊符 \n(换行符)和 ...
- C++基本面试题1
#include<iostream>using namespace std;class A{public: A(char* s) :name(s), len(strlen(name.c_s ...
- java内部类细节
1 package face_09; 2 /* 3 * 为什么内部类能直接访问外部类中的成员呢? 4 * 那是因为内部类持有了外部类的引用. 外部类名.this 5 * 6 */ 7 class Ou ...
- 多线程(Thread类中的方法线程名称)
1 package multithread; 2 3 /* 4 * 如何创建一个线程呢? 5 * 6 * 创建线程方式一:继承Thread类. 7 * 8 * 步骤: 9 * 1,定义一个类继承Thr ...
- K8S 权限控制访问之 rbac
RBAC API类型 RBAC API 所声明的四种顶级类型[Role.ClusterRole.RoleBinding 和 ClusterRoleBinding].用户可以像与其他 API 资源交互一 ...
- springboot 修改关闭banner的方法
一.修改banner. 1.1 替换banner: 需要在resources(classpath)目录中创建文件 banner.txt 1.2 上图 banner.txt 里面可以使用文字,也可以 ...
- ApacheCN React 译文集 20211118 更新
React 入门手册 零.前言 一.React 和 UI 设计简介 二.创建组件 三.管理用户交互 React 全栈项目 零.前言 一.使用 MERN 释放 React 应用 二.准备开发环境 三.使 ...
- [USACO19JAN]Train Tracking 2 P
拿到本题后,可以观察到一个性质,如果出现了 \(c_i \ne c_{i + 1}\) 那么我们一定可以确定一个位置的值,这启示着我们将 \(c_i\) 相同的部分单独拿出来考虑再将最后的答案合并.于 ...
- laravel操作Redis排序/删除/列表/随机/Hash/集合等方法全解
Song • 3563 次浏览 • 0 个回复 • 2017年10月简介 Redis模块负责与Redis数据库交互,并提供Redis的相关API支持: Redis模块提供redis与redis.con ...
- python中一个经典的参数错误
直接上代码 class Company: def __init__(self, name, staffs=[]): self.name = name self.staffs = staffs def ...