Code First模式下使用Fluent API配置实体类之间的关系(1)

在关系型数据库中,表与表之间有如下关系:
One-to-One Relationships
One-to-many or Many to One Relationships
Many-to-Many Relationships

1:1 关系 —>比如每个人只能有一个唯一的身份证号码(Person:CardId)
1:N 关系 -->班级与学生(Class:Student)、产品类型与产品(ProductType:Product)等等
N:N 关系 ---->学生与老师(Student:Teacher)、学生与课程(Student:Course)等等

1.使用Fluent API配置1对多的实体关系
添加一个班级类Clazs:

public class Clazs
    {
        public int ClazsId { get; set; }

        public string ClassName { get; set;}

        /// <summary>
        /// 配置1:N关系(导航属性:Students) class:student  双向关系
        /// 通过Class可以找到相关联的所有Student记录
        /// 
        /// </summary>
        public virtual ICollection<Student> Students { get; set; } = new List<Student>();

    }

配置导航属性Students

在Student类中也配置导航属性:

public class Student
    {
        /// <summary>
        /// EF的主键约定:Id或者是类名+Id 
        /// 既是主键又是标识列
        /// </summary>
        public long Id { get; set;}

        public string Name { get; set;}

        public int Age { get; set; }

        public string Address { get; set; }

        public DateTime CreateDateTime { get; set;}

        public decimal Height { get; set; }

        public int ClazsId { get; set; }
   
        /// <summary>
        /// 配置1:N关系(导航属性:Clazs) class:student
        /// 
        /// 通过Student可以找到相关联的Clazs
        /// </summary>
        public Clazs  Clazs { get; set; } 
    }

将下面代码添加到数据库上下文类中:(切记)

  public DbSet<Clazs> Classes { get; set;}

2.在实体配置文件的构造器中,配置1:N关系:
Class:Student -->1:N关系

StudentConfig配置类:

 //配置1:N关系,ClazsId为必填
this.HasRequired(s => s.Clazs).WithMany().HasForeignKey(s => s.ClazsId);

ClazsConfig配置类:

//配置1:N关系 class:student --->1:n关系
 this.HasMany(s => s.Students).WithRequired().HasForeignKey(s => s.ClazsId);

由于我们更改了实体类配置:
当创建好了数据库(手动创建或者是Code First模式下自动生成的)
当修改了模型类或者Context数据库上下类,
再次进行数据库交互时,会抛出异常,需要进行数据迁移操作

解决方案:
见之前写的博客: 数据迁移技术

测试用例:

public static void Test1ToNRelationShip() {
	using (SchoolContext context = new SchoolContext())
  {
      Clazs clazs = new Clazs()
      {
          ClassName = "四年级二班"
      };
      context.Classes.Add(clazs);

      Student student = new Student()
      {
          Address = "江苏南京",
          Age = 27,
          Clazs = clazs,//将已创建的Class对象与当前的Student记录建立起关联
          CreateDateTime = DateTime.Now,
          Name = "Yellow Dude",
          Height = 178
      };

      context.Students.Add(student);

      int count = context.SaveChanges();
      if (count > 0)
      {
          Console.WriteLine("数据已成功添加!");
      }
  }
}

运行完成:记录已成功添加
在这里插入图片描述
在这里插入图片描述

基于1:N关系的数据查询,实际就是外键列值的匹配

测试案例:

Student student = context.Students.Include("Clazs").FirstOrDefault<Student>(s => s.Id == 3);
Clazs clazs = student.Clazs;

Clazs clazs02 = context.Classes.Include("Students").FirstOrDefault(c => c.ClazsId == 6);

Clazs clazs03 = context.Classes.FirstOrDefault(c => c.ClazsId == 6);

//查询和clazs2相关联的所有Student记录
List<Student> students = context.Students.Where(s => s.ClazsId == clazs03.ClazsId).ToList<Student>();

Include(string navgationName) -->参数为导航属性值:
实际在EF Code First模式下,使用了Fluent API配置了导航属性以及配置了实体之间的1:n关系,在查询时EF会根据导航属性,会将关联的记录也查询出来了。

查询clazs03,相关联的Student记录也查询出来了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值