使用 Fluent API 映射实体关系 - Entity Framework

Map Entity Relationships using Fluent APIs - Entity Framework

我在申请中有以下实体。

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)

换句话说,

学生有一个 TemporaryAddress 和一个 PermanentAddress。 Student 有一个 Father 和一个 Guardian (他们可以相同,即 Guardian 也可以是父亲) Parent (Father/Guardian) 有 TemporaryAddress 和 PermanentAddress。

我如何使用 Entity Framework 的 Fluent API 实现此 ?需要在 地址和父实体 中添加哪些其他字段才能使这种关系成为可能。

谢谢。

使用您在 Entity Framework 中提供的 类 创建必要的表格和关系,从您的问题来看,您所面临的问题并不完全清楚。但是,我假设您希望 ParentAddress 关系是非可选的,而不是 Entity Framework 创建的可选默认关系。

您可以使用流利的 API 来指定需要关系。这里指定了一个 Student 需要一个非空值的 Father 属性:

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

Entity framework 默认情况下会将级联删除添加到外键关系中,因此删除 Parent 行将删除关联的 Address 行。但是,由于您可以重复使用 ParentAddress 行,因此您必须将其关闭。这可以通过删除 OneToManyCascadeDeleteConvention.

对整个 DbContext 完成

将这些放在一起,您可以使用流利的 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);
  }

}