实体框架映射。多个外键

时间:2016-02-08 02:11:50

标签: asp.net-mvc entity-framework fluent-interface

我有两张桌子

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

我需要通过Relation表将所有人与union all联系起来。 关系表有两个外键。映射它们有一个问题。映射是一对多的。 有很多关系关系有一个

我将它们映射为:

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

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

1 个答案:

答案 0 :(得分:1)

根据Relations表中的每个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); 

更新

首先让我先提一个建议。我认为你的表Relation没有扮演任何角色,你只有那些专栏。如果一个人只有父母,我会将你的模型改为:

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您要加载与Relation相关的People个实体,但您还要加载与每个People相关的Relation,同时People所在的Relation也是People,因此,如果您的数据正确相关,则不需要执行最后一次选择var Peoplelist = MyDbContext.People.Include(p=>p.Relations).ToList(); 导航在执行查询时将加载属性,因此,该查询应该是这样的:

newAccountButton