【问题标题】:How to have two different navigation properties of the same another entity type using attributes如何使用属性具有相同的另一个实体类型的两个不同的导航属性
【发布时间】:2016-03-03 06:54:00
【问题描述】:

我有两个实体:

//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 计数 0,它应该是 5,因为在数据库中我在详细信息表中有 5 行。我可以通过运行以下代码来确认这一点:

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

我得到了五个 SlavePosition。

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    到这里

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多