如何在 Entity Framework 6 Code First 中创建多个 1:1 外键关系?

How do I create multiple 1:1 foreign key relationships in Entity Framework 6 Code First?

假设我有三个表,每个表都有一个名为 Id:

的主键
TableA
------
Id

TableB
------
Id

TableC
-----
Id

目的是让这些实体中的每一个彼此进行一对一导航 属性 以便我可以在给定任何实体的任何方向上导航。不幸的是,我还没有找到 [Key][ForeignKey] 和导航属性的组合,允许每个实体多次

例如,这个有效(Entity Framework 认为 TableA 是 1:1 关系中的委托人):

public class TableA
{
    [Key]
    [Required]
    public Guid Id { get; set; }

    public virtual TableB TableB { get; set; }
    public virtual TableC TableB { get; set; }
}

public class TableB
{
    [Key]
    [ForeignKey("TableA")]
    [Required]
    public Guid Id { get; set; }

    public virtual TableA TableA { get; set; }
}

但这不起作用:

public class TableB
{
    [Key]
    [ForeignKey("TableA,TableC")] // The constructor documentation says this will work, but at runtime it throws an exception
    [Required]
    public Guid Id { get; set; }

    public virtual TableA TableA { get; set; }

    public virtual TableC TableC { get; set; }
}

这也不行:

public class TableB
{
    [Key]
    [Required]
    public Guid Id { get; set; }

    [ForeignKey("Id")]
    public virtual TableA TableA { get; set; }

    [ForeignKey("Id")]
    public virtual TableC TableC { get; set; }
}

如何使用属性允许这些关系?目前,如果我想从 TableB 导航到 TableC,我必须通过 TableA 导航,导致额外的不必要的数据库查找。似乎 Entity Framework 想要在可能存在 none.

的地方强制建立等级关系

我想你需要的是这样的模型:

public class TableA
{
    [Key]
    public Guid Id { get; set; }

    public virtual TableB TableB { get; set; }
    public virtual TableC TableC { get; set; }
}
public class TableB
{
    [Key]
    [ForeignKey("TableA")]
    public Guid Id { get; set; }

    public virtual TableA TableA { get; set; }

    public virtual TableC TableC { get; set; }
}

public class TableC
{
    [Key]
    [ForeignKey("TableB")]
    public Guid Id { get; set; }

    public virtual TableB TableB { get; set; }

    [Required]
    public virtual TableA TableA { get; set; }
}

您不需要在 TableB 实体中为 TableC 导航 属性 指定外键 属性,因为 TableB 是关系中的主体B和C之间

更新

尝试删除 Required 数据注释并以这种方式配置关系,覆盖上下文中的 OnModelCreating 方法:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
        modelBuilder.Entity<TableA>().HasOptional(a => a.TableC).WithOptionalPrincipal(c => c.TableA);

        base.OnModelCreating(modelBuilder);
  }