EF Core中实体之间关系的配置有如下三种:
一对多:HasOne(XXX).WithMany(XXX)
一对一:HasOne(XXX).WithOne (XXX)
多对多:HasMany(XXX).WithMany(XXX)
本文主要说说一对多关系,一对多关系一般分为双向一对多和单向一对多,双向一堆多关系一般两个表之间关系都比较密切,如果一个学生跟他的教育经历和工作经历都是关系密切的;相反单向一对多关系关系就没有那个密切了,比如用户表同用户订单、请假、外勤等。
主要讲解学生跟教育经历的关系,一个学生可以有小学、初中、高中、大学等多个教育经历。首先建立两个表的实体类,学生表中有个List<教育经历>的List,用来指向多个教育经历;教育经历表中有个学生属性用来指向所属那个学生。
两个实体类有了就可以配置一对多关系了,一对多关系的配置可以放在学生配置类也可以放在教育经历配置类中,这里先介绍放在教育经历配置类中,本文后面讲解放到学生类中的方法。
具体代码如下:
实体类代码:
public class Person { public int Id { get; set; } public string Name { get; set; } public int Height { get; set; } public List<Education> educations { get; set; } = new List<Education>(); } public class Education { public int Id { get; set; } //生成数据库时默认新增一个外键类,列名为本属性名+Id public Person Person { get; set; } //需要在配置文件告知这一列是外键列,否则数据库将会新增此列 public string PersonId { get; set; } public string SchoolName { get; set; } }
教育经历配置类代码:
public class EducationConfig : IEntityTypeConfiguration<Education> { public void Configure(EntityTypeBuilder<Education> builder) { builder.ToTable("Educations"); //设置外键 builder.HasOne<Person>(e=>e.Person) .WithMany(a=>a.educations).HasForeignKey(c=>c.PersonId).IsRequired(); } }
程序实例(主要介绍增加数据实例):
至此一对多关系以及配置完成,在进行代码编写之前,需要执行Add-Migration命令将修改更新到数据库才可以,以下是在学生表格增加一个测试学生,然后在教育经历里面增加了初中及高中两条教育经历的代码。
Person person = new Person(); person.Name = "测试学生"; Education education1 = new Education(); education1.SchoolName = "初中"; Education education2 = new Education(); education2.SchoolName = "高中"; person.educations.Add(education1); person.educations.Add(education2); db.Persons.Add(person); db.SaveChanges();
本例列举了一个用户表及用户请假信息表,一对多关键建立在请假表中。
实体类代码:
public class User { public int Id { get; set; } public string Name { get; set; } } public class Leave { public int Id { get; set; } public User Requester { get; set; } public User Approver { get; set; } public string Remark { get; set; } }
请假表实体配置代码:
public class LeaveConfig : IEntityTypeConfiguration<Leave> { public void Configure(EntityTypeBuilder<Leave> builder) { builder.ToTable("Leaves"); builder.HasOne<User>(e => e.Requester).WithMany().OnDelete(DeleteBehavior.NoAction); builder.HasOne<User>(e => e.Approver).WithMany().OnDelete(DeleteBehavior.NoAction); } }
增加及查询测试实例代码:
User user = new User { Name = "测试人员" }; Leave leave = new Leave { Remark = "家中有事", Requester = user,Approver=user }; db.Leaves.Add(leave); db.SaveChanges(); var list = db.Leaves.FirstOrDefault();
在一对多关系的查询中比较常见的需求是查询子表时把父表信息带出来,查询父表时把子表信息带出来,EF Core主要使用Include关键字实现。
1、通过父表数据关联查询子表数据
var model = db.Persons.Include(a=>a.educations).Single(a=>a.Id == 1);
以上语句将父表Id为1的学生信息及相对应的教育经历都查询出来了。
2、通过子表数据查询父表数据(结果为一条数据)
var list = db.Educations.Include(a => a.Person).Single(a => a.Id == 2);
双向导航一对多关系配置,也可以配置在父表中,代码如下:
public class PersonConfig : IEntityTypeConfiguration<Person> { public void Configure(EntityTypeBuilder<Person> builder) { builder.ToTable("Persons"); builder.Property(p=>p.Name).IsRequired(); //一对多关系 builder.HasMany<Education>(e => e.educations).WithOne(c=>c.Person).IsRequired(); } }
实际开发中有很多树形机构的数据,例如公司组织架构表、导航菜单、地区结构表等等,这里说说树形结构的表一对多关系配置。
如:集团名称-权属企业名称-部门名称-子部门名称
//实体类 public class OrgUnit { public int Id { get; set; } public string Name { get; set; } public OrgUnit Parent { get; set; } public int? ParentId { get; set; } public List<OrgUnit> Children { get; set; } = new List<OrgUnit>(); } //实体配置类 public class OrgUnitConfig : IEntityTypeConfiguration<OrgUnit> { public void Configure(EntityTypeBuilder<OrgUnit> builder) { builder.ToTable("OrgUnits"); builder.HasKey(x => x.Id); //根节点没有父层Id没有值,非空约束不能要 builder.HasOne<OrgUnit>(e => e.Parent).WithMany(e => e.Children).IsRequired(false).HasForeignKey(x=>x.ParentId).OnDelete(DeleteBehavior.NoAction); } } //测试增加数据代码 OrgUnit parent1 = new OrgUnit() { Name = "父节点1" }; OrgUnit child11 = new OrgUnit() { Name = "子节点11", Parent = parent1 }; OrgUnit child12 = new OrgUnit() { Name = "子节点12", Parent = parent1 }; parent1.Children.Add(child11); parent1.Children.Add(child12); db.OrgUnits.Add(parent1); db.SaveChanges();
- EF Core 实战教程(八)一对多关系配置(1125)
- EF Core 实战教程(四)EF Core如何设置主键(909)
- EF Core 实战教程(六)如何查看EF Core生成的Sql语句(892)
- EF Core 实战教程(七)通过读取appsetting.json数据库链接字符串链接数据库(820)
- EF Core 实战教程(三)Fluent Api配置详解(595)
- EF Core 实战教程(一)配置环境及使用code first 创建数据库(587)
- EF Core 实战教程(五)Migrations深入研究及使用详解(525)
- EF Core 实战教程(二)实现基本的查询、增加、修改、删除功能(514)
- 解决Asp.net Core Razor页面调试时无法实时更新(502)
- EF Core实现充血模型(478)
- 2025年3月 (1)
- 2024年6月 (2)
- 2024年5月 (2)
- 2024年4月 (4)
- 2024年3月 (30)
- 2024年1月 (4)
- 2023年12月 (2)
- 2023年11月 (4)
- 2023年10月 (4)
- 2023年9月 (6)
- 2023年3月 (2)
- 2023年2月 (1)
- 2023年1月 (1)
- 2022年12月 (1)
- 2022年9月 (21)
- 2022年8月 (10)
- 2022年7月 (3)
- 2022年4月 (1)
- 2022年3月 (13)
- 2021年8月 (1)
- 2021年3月 (1)
- 2020年12月 (42)
- 2020年11月 (7)
- 2020年10月 (5)
- 2020年8月 (1)
- 2020年6月 (1)
- 2020年3月 (2)
- 2019年12月 (8)
- 2019年11月 (3)
- 2019年9月 (1)
- 2019年4月 (1)
- 2019年3月 (6)
- 2019年2月 (1)
- 2018年7月 (7)
- 1.asp.net mvc内微信pc端、H5、JsApi支付方式总结(5702)
- 2.各大搜索网站网站收录提交入口地址(3201)
- 3.Windows 10休眠文件更改存储位置(3164)
- 4.ECharts仪表盘实例及参数使用详解(3095)
- 5.windows 10安装myeclipse 10破解补丁cracker.jar、run.bat闪退解决办法(2992)
- 6.HTML5 WebSocket与C#建立Socket连接实现代码(2866)
- 7.华为鸿蒙系统清除微信浏览器缓存方法(2784)
- 8.CERT_HAS_EXPIRED错误如何解决(2249)
- 9.Js异步async、await关键字详细介绍(lambda表达式中使用async和await关键字)(2189)
- 10.HBuilder编辑器格式化代码(2118)