Entity Framework 映射。多个外键

Entity Framework Mapping. Multiple Foreign keys

我有两个table

People                  Relation
-------------           -----------------
Id (int)                Id (int)
Name (string)           ParentPeopleId (int)
                        ChildPeopleId (int)

我需要通过 Relation table 和 union all 获取所有人。 关系 table 有两个外键。映射它们存在一个问题。映射是一对多的。 人物有很多关系关系有一个人物

我把它们映射成这样:

HasRequired(r=> r.People).WithMany(p=>p.Relation).HasForeignKey(r=>r.ChildPeopleId);

那么,如何映射第二个外键?

对于 Relations table 中的每个 FK 列,您的 Relation 实体中应该有一个导航 属性(这不是强制性的,但强制性的是在关系中涉及的实体之间至少有一个导航属性)。在这种情况下,您在 PeopleRelations 之间有两个关系,导航 属性 表示关系中的一端。你的模型可能是这样的:

public class Relation
{
  public int Id {get;set;}

  public int ParentPeopleId {get;set;}

  public int ChildPeopleId {get;set;}

  public virtual People ParentPeople {get;set;}
  public virtual People ChildPeople {get;set;}
}
public class People
{
   public int Id {get;set;}
   public string Name {get;set;}

   public virtual ICollection<Relation> ParentRelations {get;set;}
   public virtual ICollection<Relation> ChildRelations {get;set;}

}

Fluent Api 配置如下:

HasRequired(r=> r.ParentPeople ).WithMany(p=>p.ParentRelations ).HasForeignKey(r=>r.ParentPeopleId);   
HasRequired(r=> r.ChildPeople).WithMany(p=>p.ChildRelations ).HasForeignKey(r=>r.ChildPeopleId );

现在,如果您不想在 People 实体中使用其中一个集合导航属性,则可以创建单向关系。例如,如果您不想要 ParenRelations 导航 属性,您可以按如下方式配置该关系:

HasRequired(r=> r.ParentPeople).WithMany().HasForeignKey(r=>r.ParentPeopleId); 

更新

让我先从一个建议开始。我觉得你的 table Relation 没有发挥任何作用,因为你只有那些专栏。如果一个人只有 parent,我会将您的模型更改为以下内容:

public class People
{
   public int Id {get;set;}
   public string Name {get;set;}

   public int ParentId {get;set;}
   public virtual People Parent {get;set;}
   public virtual ICollection<People> Children {get;set;}
}

你的关系配置为:

HasOptional(r=> r.Parent).WithMany(p=>p.Children).HasForeignKey(r=>r.ParentId);

现在回到您的 current model,EF 将您的 ChildPeopleId 属性 视为一个简单的标量列,它不知道它是一个 FK 列,这就是我上面建议的方式映射两个关系而不是一个关系。

另一件事,下面一行

var Peoplelist = MyDbContext.People.Include(p=>p.Relations.Select(r=>r.People)).ToList();

您告诉 EF 您想要加载与 People 相关的 Relation 个实体,而且您还想加载与每个 Relation 相关的 People ],这与 Relation 的来源相同 People,因此,如果您的数据正确关联,则无需执行最后一个 select,即People 导航 属性 将在您执行查询时加载,因此,该查询应该是这样的:

var Peoplelist = MyDbContext.People.Include(p=>p.Relations).ToList();