使用Fluent api -实体框架映射实体关系

本文关键字:实体 框架 关系 映射 Fluent api 使用 | 更新日期: 2023-09-27 18:12:46

我在应用程序中有以下实体。

Student
Parent (This Parent can be Father/Guardian)
Address

它们定义了以下类:

public Class Student
{
    public int StudentId {get; set;}
    //Addresses
    public Address TemporaryAddress {get;set;}
    public Address PermanentAddress {get;set;}
    //Parent
    public Parent Father {get;set;}
    public Parent Guardian {get;set;}
}
public class Parent
{
    public int ParentId {get;set;}
    public string Name {get;set;}
    //Addresses
    public Address TemporaryAddress {get;set;}
    public Address PermanentAddress {get;set;}
}
public class Address
{
    public int AddressId {get;set;}
    public string Country  {get;set;}
    public string State  {get;set;}
    public string Town  {get;set;}
    public string House#  {get;set;}
}

我希望它们之间有如下的关系

Student
        ->TemporaryAddress (Address)
        ->PermanentAddress (Address)
        ->Father           (Parent)
                ->TemporaryAddress (Address)
                ->PermanentAddress (Address)
        ->Guardian         (Parent)
                ->TemporaryAddress (Address)
                ->PermanentAddress (Address)

也就是说

Student有一个TemporaryAddress和一个PermanentAddress。学生有一个父亲和一个监护人(他们可以是相同的,即监护人也可以是父亲)家长(父亲/监护人)有临时地址和永久地址。

我怎么能实现这个使用实体框架的流畅api ?需要在Address和父实体中添加哪些其他字段才能使这种关系成为可能?

谢谢。

使用Fluent api -实体框架映射实体关系

使用实体框架提供的类创建必要的表和关系,并且从您的问题中并不完全清楚您面临的问题。但是,我假设您希望ParentAddress关系是非可选的,而不是实体框架创建的可选的默认关系。

可以使用fluent API指定需要的关系。这里指定Student需要Father属性的非空值:

modelBuilder
  .Entity<Student>()
  .HasRequired(p => p.Father);

实体框架将默认添加级联删除外键关系,因此删除Parent行将删除相关的Address行。但是,由于您可以重用ParentAddress行,因此必须关闭此功能。这可以通过删除OneToManyCascadeDeleteConvention来完成整个DbContext

把这些放在一起,你可以使用fluent API创建一个DbContext:

public class Context : DbContext {
  public IDbSet<Student> Students { get; set; }
  public IDbSet<Parent> Parents { get; set; }
  public IDbSet<Address> Addresses { get; set; }
  protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    modelBuilder
      .Entity<Student>()
      .HasRequired(p => p.Father);
    modelBuilder
      .Entity<Student>()
      .HasRequired(p => p.Guardian);
    modelBuilder
      .Entity<Student>()
      .HasRequired(p => p.PermanentAddress);
    modelBuilder
      .Entity<Student>()
      .HasRequired(p => p.TemporaryAddress);
    modelBuilder
      .Entity<Parent>()
      .HasRequired(p => p.PermanentAddress);
    modelBuilder
      .Entity<Parent>()
      .HasRequired(p => p.TemporaryAddress);
  }
}