EF Core04


EF Core 实体间对应关系

一对一:

builder.HasOne(x => x.T).WithOne(d => d.T2).HasForeignKey(d => d.T2Key);

一对多:

builder.HasOne(x=>x.T).WithMany(x=>x.T2s)

多对多:

builder.HasMany(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
    {
        /// 
        /// 身份证号
        /// 
        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
    {
        /// 
        /// 学号
        /// 
        public long Id { get; set; } 
        public string Name { get; set; } 
        public string ClassName { get; set; }
        /// 
        /// 身份证
        /// 
        public IDCard IdCard { get; set; }
        /// 
        /// 身份证号
        /// 
        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 iDCards { get; set; }
        public DbSet 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
    {
        public void Configure(EntityTypeBuilder builder)
        {
            //也可以在学生配置中进行,
            //HasOne=> 一个学生对应 WithOne 一个身份证  通过 学生的身份ID关联
            builder.HasOne(x => x.student).WithOne(d => d.IdCard).HasForeignKey(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? childers { get; set; }
    }

ChilderConfig.cs

 internal class ChilderConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("ZuChilder");
            //一个家里有多个孩子  
            builder.HasOne(x=>x.home).WithMany(x=>x.childers).IsRequired();
        }
    }

HomeConfig.cs

  internal class HomeConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("ZuHome");
            //多个孩子对应一个家庭
            //与ChilderConfig 的任选其一 builder.HasOne(x=>x.home).WithMany(x=>x.childers).IsRequired();)
            //builder.HasMany(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 cs= new List();
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; }
        /// 
        /// 地址
        /// 
        public string Location { get; set; }
        /// 
        /// 占地面积
        /// 
        public double Area { get; set; }
        public List suppliers { get; set; } = new List();

    }

Supplier

    internal class Supplier
    {
        public int Id { get; set; }
        public string SupplierName { get; set; }
        public string Address { get; set; }
        /// 
        /// 供应物品类型
        /// 
        public string CommodityType { get; set; }
        public List supermarkets { get; set; } = new List();
    }

 SupermarketConfig

    internal class SupermarketConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("ZuSupermarket");
            //或者这里配置
            //builder.HasMany(x => x.suppliers).WithMany(x => x.supermarkets)
             //  .UsingEntity(mt => mt.ToTable("ZuMidSupermarket_Supplier"));//对应的中间表
        }
    }

SupplierConfig

   internal class SupplierConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("ZuSupplier");
            //多对多
            builder.HasMany(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}m2");
    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}m2");
    } 
} 
Console.WriteLine("done..");