EF Core 实体间对应关系
一对一:
builder.HasOne<T>(x => x.T).WithOne(d => d.T2).HasForeignKey<T>(d => d.T2Key);
一对多:
builder.HasOne<T>(x=>x.T).WithMany(x=>x.T2s)
多对多:
builder.HasMany<T1>(x => x.T1s).WithMany(x => x.T2s).UsingEntity(mt=>mt.ToTable("T1_T2"));//对应的中间表
一对一
例子:一个学生对应一个身份证
创建项目
IDCard:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF_04 { public class IDCard { /// <summary> /// 身份证号 /// </summary> public long Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Address { get; set; } public Student student { get; set; } } }
Student.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF_04 { public class Student { /// <summary> /// 学号 /// </summary> public long Id { get; set; } public string Name { get; set; } public string ClassName { get; set; } /// <summary> /// 身份证 /// </summary> public IDCard IdCard { get; set; } /// <summary> /// 身份证号 /// </summary> public long CardId { get; set; } } }
--StuDBcontext.cs
using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF_04 { internal class StuDBcontext:DbContext { public DbSet<IDCard> iDCards { get; set; } public DbSet<Student> students { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); string ConStr = "Server =.; Database = Demo; User Id = sa; Password = admin123;connection timeout=600"; optionsBuilder.UseSqlServer(ConStr); //optionsBuilder.LogTo(Console.WriteLine); //增加日志记录 } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); } } }
StudentConfig.cs--配置一对一关系
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace EF_04 { internal class StudentConfig : IEntityTypeConfiguration<IDCard> { public void Configure(EntityTypeBuilder<IDCard> builder) { //也可以在学生配置中进行, //HasOne=> 一个学生对应 WithOne 一个身份证 通过 学生的身份ID关联 builder.HasOne<Student>(x => x.student).WithOne(d => d.IdCard).HasForeignKey<Student>(d => d.CardId); } } }
执行数据库生成命令:
add-migration XXX
update-database
来看数据库:
写入数据:只需要写入一个实体就够了。
Program.cs
using EF_04; IDCard card=new IDCard(); card.Name = "张三"; card.Age = 10; card.Address = "北京东城区"; Student student = new Student(); student.ClassName = "三年级"; student.Name = "张三"; student.IdCard = card; using (StuDBcontext stu = new StuDBcontext()) { await stu.AddAsync(student); await stu.SaveChangesAsync(); } Console.WriteLine("done..");
查看输出和数据库:
来试试查询:
顺便查看SQL语句
optionsBuilder.LogTo(Console.WriteLine); //增加日志记录
修改Program
using (StuDBcontext stu = new StuDBcontext()) { var student= stu.students.Include(args=>args.IdCard).FirstOrDefault();if (stu!=null) { Console.WriteLine("姓名:" + student.Name); Console.WriteLine("年龄:" + student.IdCard.Age); Console.WriteLine("身份证号:" + student.CardId); Console.WriteLine("家庭地址:" + student.IdCard.Address); Console.WriteLine("班级:" + student.Name); } } Console.WriteLine("done..");
运行看看:
一对多
例子:一个家庭可以有多个孩子
添加4个类
Childer.cs
internal class Childer { public short Id { get; set; } public string Name{ get; set; } public int Age { get; set; } public string Gender { get; set; } public Home home { get; set; } }
Home.cs
internal class Home { public int Id { get; set; } public string FatherName { get; set; } public string MotherName { get; set; } public List<Childer>? childers { get; set; } }
ChilderConfig.cs
internal class ChilderConfig : IEntityTypeConfiguration<Childer> { public void Configure(EntityTypeBuilder<Childer> builder) { builder.ToTable("ZuChilder"); //一个家里有多个孩子 builder.HasOne<Home>(x=>x.home).WithMany(x=>x.childers).IsRequired(); } }
HomeConfig.cs
internal class HomeConfig : IEntityTypeConfiguration<Home> { public void Configure(EntityTypeBuilder<Home> builder) { builder.ToTable("ZuHome"); //多个孩子对应一个家庭 //与ChilderConfig 的任选其一 builder.HasOne<Home>(x=>x.home).WithMany(x=>x.childers).IsRequired();) //builder.HasMany<Childer>(x=>x.childers).WithOne(x=>x.home).IsRequired(); } }
把实体加入到DBcontext
执行数据库生成命令:
add-migration XXX
update-database
来看数据库:
新增几条数据
Program
Home home=new Home(); home.FatherName = "张三"; home.MotherName = "李四"; Childer c1=new Childer(); c1.Name = "张三丰"; c1.Age = 55; c1.Gender = "男"; Childer c2 = new Childer(); c2.Name = "张四丰"; c2.Age = 55; c2.Gender = "男"; Childer c3 = new Childer(); c3.Name = "张无忌"; c3.Age = 55; c3.Gender = "男"; List<Childer> cs= new List<Childer>(); cs.Add(c1); cs.Add(c2); cs.Add(c3); home.childers=cs; using (StuDBcontext stu = new StuDBcontext()) { await stu.AddAsync(home); await stu.SaveChangesAsync(); } Console.WriteLine("done..");
来看数据库:
查询数据:
修改Program
using (StuDBcontext stu = new StuDBcontext()) { var home = stu.homes.Include(x => x.childers).FirstOrDefault(); if (home != null) { Console.WriteLine($"父亲:{home.FatherName}母亲:{home.MotherName}"); foreach (var item in home.childers) { Console.WriteLine($" 孩子:{item.Name}今年{item.Age}"); } } } Console.WriteLine("done..");
输入:
多对多
例子:一个供应商可以供应多个超市,一个超市可以销售多个供应商的货
新增加四个类:
Supermarket
internal class Supermarket { public int Id { get; set; } public string SupermarketName { get; set; } /// <summary> /// 地址 /// </summary> public string Location { get; set; } /// <summary> /// 占地面积 /// </summary> public double Area { get; set; } public List<Supplier> suppliers { get; set; } = new List<Supplier>(); }
Supplier
internal class Supplier { public int Id { get; set; } public string SupplierName { get; set; } public string Address { get; set; } /// <summary> /// 供应物品类型 /// </summary> public string CommodityType { get; set; } public List<Supermarket> supermarkets { get; set; } = new List<Supermarket>(); }
SupermarketConfig
internal class SupermarketConfig : IEntityTypeConfiguration<Supermarket> { public void Configure(EntityTypeBuilder<Supermarket> builder) { builder.ToTable("ZuSupermarket"); //或者这里配置 //builder.HasMany<Supplier>(x => x.suppliers).WithMany(x => x.supermarkets) // .UsingEntity(mt => mt.ToTable("ZuMidSupermarket_Supplier"));//对应的中间表 } }
SupplierConfig
internal class SupplierConfig : IEntityTypeConfiguration<Supplier> { public void Configure(EntityTypeBuilder<Supplier> builder) { builder.ToTable("ZuSupplier"); //多对多 builder.HasMany<Supermarket>(x => x.supermarkets).WithMany(x => x.suppliers) .UsingEntity(mt=>mt.ToTable("ZuMidSupermarket_Supplier"));//对应的中间表 } }
执行数据库生成命令:
add-migration XXX
update-database
看数据库:
新增几条数据试试:
Supermarket WalMart = new Supermarket() { SupermarketName = "沃尔玛", Location = "全球连锁", Area = 2000 }; Supermarket Carrefour= new Supermarket() { SupermarketName = "家乐福", Location = "欧美连锁", Area = 2000 }; Supermarket TrustMart = new Supermarket() { SupermarketName = "好又多", Location = "亚洲连锁", Area = 2000 }; Supermarket RTMART = new Supermarket() { SupermarketName = "大润发", Location = "全国连锁", Area = 2000 }; Supermarket TESCO = new Supermarket() { SupermarketName = "乐购", Location = "全国连锁", Area = 2000 }; Supplier s1 = new Supplier() { SupplierName = "腾远供应链公司", Address = "山西腾远供应链公司", CommodityType = "数码3C" }; Supplier s2 = new Supplier() { SupplierName = "亮皓供应链公司", Address = "湖南亮皓供应链公司", CommodityType = "家装灯具" }; Supplier s3 = new Supplier() { SupplierName = "秋蓝供应链公司", Address = "江西秋蓝供应链公司", CommodityType = "家用清洁" }; Supplier s4 = new Supplier() { SupplierName = "江涛供应链公司", Address = "湖北江涛供应链公司", CommodityType = "金银首饰" }; Supplier s5 = new Supplier() { SupplierName = "秋泰供应链公司", Address = "浙江秋泰供应链公司", CommodityType = "五金建材" }; Supplier s6 = new Supplier() { SupplierName = "创宇供应链公司", Address = "上海创宇供应链公司", CommodityType = "数码3C" }; Supplier s7 = new Supplier() { SupplierName = "言洋供应链公司", Address = "山东言洋供应链公司", CommodityType = "图书音像" }; Supplier s8 = new Supplier() { SupplierName = "城松供应链公司", Address = "哈尔滨城松供应链公司", CommodityType = "食品干果" }; Supplier s9 = new Supplier() { SupplierName = "旭亿供应链公司", Address = "辽宁旭亿供应链公司", CommodityType = "五金建材" }; Supplier s10 = new Supplier() { SupplierName = "渝山供应链公司", Address = "河北渝山供应链公司", CommodityType = "彩妆美容" }; Supplier s11 = new Supplier() { SupplierName = "建秦供应链公司", Address = "新疆建秦供应链公司", CommodityType = "食品肉类" }; Supplier s12 = new Supplier() { SupplierName = "河清供应链公司", Address = "新疆河清供应链公司", CommodityType = "水产食品" }; WalMart.suppliers.Add(s1); s1.supermarkets.Add(WalMart); WalMart.suppliers.Add(s2); s2.supermarkets.Add(WalMart); Carrefour.suppliers.Add(s1); s1.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s2); s2.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s3); s3.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s4); s4.supermarkets.Add(Carrefour); TrustMart.suppliers.Add(s5); s5.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s6); s6.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s7); s7.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s8); s8.supermarkets.Add(TrustMart); RTMART.suppliers.Add(s9); s9.supermarkets.Add(RTMART); RTMART.suppliers.Add(s10); s10.supermarkets.Add(RTMART); RTMART.suppliers.Add(s11); s11.supermarkets.Add(RTMART); TESCO.suppliers.Add(s12); s12.supermarkets.Add(TESCO); using (StuDBcontext stu = new StuDBcontext()) { await stu.AddAsync(WalMart); await stu.AddAsync(Carrefour); await stu.AddAsync(TrustMart); await stu.AddAsync(RTMART); await stu.AddAsync(TESCO); await stu.SaveChangesAsync(); } Console.WriteLine("done..");
看看数据库:
来试试查询一下:
修改-Program
Supermarket WalMart = new Supermarket() { SupermarketName = "沃尔玛", Location = "全球连锁", Area = 2000 }; Supermarket Carrefour= new Supermarket() { SupermarketName = "家乐福", Location = "欧美连锁", Area = 2000 }; Supermarket TrustMart = new Supermarket() { SupermarketName = "好又多", Location = "亚洲连锁", Area = 2000 }; Supermarket RTMART = new Supermarket() { SupermarketName = "大润发", Location = "全国连锁", Area = 2000 }; Supermarket TESCO = new Supermarket() { SupermarketName = "乐购", Location = "全国连锁", Area = 2000 }; Supplier s1 = new Supplier() { SupplierName = "腾远供应链公司", Address = "山西腾远供应链公司", CommodityType = "数码3C" }; Supplier s2 = new Supplier() { SupplierName = "亮皓供应链公司", Address = "湖南亮皓供应链公司", CommodityType = "家装灯具" }; Supplier s3 = new Supplier() { SupplierName = "秋蓝供应链公司", Address = "江西秋蓝供应链公司", CommodityType = "家用清洁" }; Supplier s4 = new Supplier() { SupplierName = "江涛供应链公司", Address = "湖北江涛供应链公司", CommodityType = "金银首饰" }; Supplier s5 = new Supplier() { SupplierName = "秋泰供应链公司", Address = "浙江秋泰供应链公司", CommodityType = "五金建材" }; Supplier s6 = new Supplier() { SupplierName = "创宇供应链公司", Address = "上海创宇供应链公司", CommodityType = "数码3C" }; Supplier s7 = new Supplier() { SupplierName = "言洋供应链公司", Address = "山东言洋供应链公司", CommodityType = "图书音像" }; Supplier s8 = new Supplier() { SupplierName = "城松供应链公司", Address = "哈尔滨城松供应链公司", CommodityType = "食品干果" }; Supplier s9 = new Supplier() { SupplierName = "旭亿供应链公司", Address = "辽宁旭亿供应链公司", CommodityType = "五金建材" }; Supplier s10 = new Supplier() { SupplierName = "渝山供应链公司", Address = "河北渝山供应链公司", CommodityType = "彩妆美容" }; Supplier s11 = new Supplier() { SupplierName = "建秦供应链公司", Address = "新疆建秦供应链公司", CommodityType = "食品肉类" }; Supplier s12 = new Supplier() { SupplierName = "河清供应链公司", Address = "新疆河清供应链公司", CommodityType = "水产食品" }; WalMart.suppliers.Add(s1); s1.supermarkets.Add(WalMart); WalMart.suppliers.Add(s2); s2.supermarkets.Add(WalMart); Carrefour.suppliers.Add(s1); s1.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s2); s2.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s3); s3.supermarkets.Add(Carrefour); Carrefour.suppliers.Add(s4); s4.supermarkets.Add(Carrefour); TrustMart.suppliers.Add(s5); s5.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s6); s6.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s7); s7.supermarkets.Add(TrustMart); TrustMart.suppliers.Add(s8); s8.supermarkets.Add(TrustMart); RTMART.suppliers.Add(s9); s9.supermarkets.Add(RTMART); RTMART.suppliers.Add(s10); s10.supermarkets.Add(RTMART); RTMART.suppliers.Add(s11); s11.supermarkets.Add(RTMART); TESCO.suppliers.Add(s12); s12.supermarkets.Add(TESCO); using (StuDBcontext stu = new StuDBcontext()) { var supermarket= await stu.supermarkets.Include(x=>x.suppliers).FirstAsync(x => x.SupermarketName == "沃尔玛"); Console.WriteLine($"超市名:{supermarket.SupermarketName} 类型:{supermarket.Location} 占地:{supermarket.Area}m²"); Console.WriteLine("对应供应商:"); foreach (var item in supermarket.suppliers) { Console.WriteLine($" {item.SupplierName} ,所在地:{item.Address},经营种类:{item.CommodityType}"); } Console.WriteLine("-----------------------------------------------分割线------------------------------------------"); var supplier=await stu.suppliers.Include(x => x.supermarkets).FirstAsync(x => x.SupplierName == "亮皓供应链公司"); Console.WriteLine($"供应商:{supplier.SupplierName},,所在地:{supplier.Address},经营种类:{supplier.CommodityType}"); Console.WriteLine("供应超市有:"); foreach (var item in supplier.supermarkets) { Console.WriteLine($"超市名:{item.SupermarketName} 类型:{item.Location} 占地:{item.Area}m²"); } } Console.WriteLine("done..");