如何使用属性为同一另一个实体类型提供两个不同的导航属性

时间:2016-03-03 06:54:01

标签: entity-framework foreign-key-relationship navigation-properties icollection

我有两个实体:

//The master table/entity
[TABLE("POSITIONS")]
public class Position{
   [Key,Column("POSITIONID")]
   public int PositionId{get;set;}
   [Column("POSITIONNAME")]
   public string PositionName{get;set;}
}

//The detail table/entity
[TABLE("SLAVE_POSITIONS")]
public class SlavePosition{   
   [Key,Column("MASTERPOSID",Order=0)]
   public int MasterPosId{get;set;}
   [KEY,Column("SLAVEPOSID",Order=1)]
   public string SlavePosId{get;set;}

   [ForeignKey("MasterPosId")]
   public virtual Position MasterPosition {get;set;}
   [ForeignKey("SlavePosId")]
   public virtual Position SlavePosition {get;set;}
}

在SlavePosition中,正如您所看到的,该实体与Position的FK关系有两列。这种布局效果很好。现在我还需要将此集合属性添加到Position实体:

 public virtual ICollection<SlavePosition> SlavePositions{get;set;}

但显然EF感到困惑,我得到{"ORA-00904: \"Extent1\".\"Position_PositionId\": invalid identifier"}错误。 如果我这样声明:

 [ForeignKey("SlavePositionId")]
 public virtual ICollection<SlavePosition> SlavePositions { get; set; }

然后像这样获取PositionId = 1的位置:

 Position pos= dbContext.Positions.SingleOrDefault(x=>x.PositionId==1);

我没有得到任何错误,但是我得到了SlavePOsitions,它应该是5,因为在数据库中我在详细信息表中有5行。我可以通过运行以下代码来确认这一点:

IEnumerable<SlavePositions> slavePositions= dbcontext.SlavePositions.Where(x=>x.MasterPositionId==1);

我得到五个SlavePosition。

此集合属性的正确属性应该是什么?

1 个答案:

答案 0 :(得分:2)

我终于明白了。我的错误在于引用的依赖属性名称。而不是SlavePositionId我应该放MasterPositionId

这是有道理的,因为Position实体充当主表,而在现实世界中,外键关系是在详细信息表上设置的,而不是主表关系。由于从属实体中没有与主实体中的PK同名的属性,并且有多个属性具有到同一主实体的Foreignkey,因此EF需要更多信息。通过指定对{ICollection>导航属性ForeignKey("MasterPositionId"),我指示EF应将Dependent end point属性视为MasterPositionId。所以我改变了这个

 [ForeignKey("SlavePositionId")]
 public virtual ICollection<SlavePosition> SlavePositions { get; set; }

到这个

 [ForeignKey("MasterPositionId")]
 public virtual ICollection<SlavePosition> SlavePositions { get; set; }

事实上前者本身也没有错,它只是不适合这种情况。但如果我想要一个MasterPositions的集合,这将非常适合。

相关问题