如何使用属性拥有相同的另一个实体类型的两个不同导航属性
How to have two different navigation properties of the same another entity type using attributes
我有两个实体:
//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 行的详细信息 table。我可以通过 运行 下面的代码来确认这一点:
IEnumerable<SlavePositions> slavePositions= dbcontext.SlavePositions.Where(x=>x.MasterPositionId==1);
我得到五个 SlavePosition。
此集合的正确属性应该是什么 属性?
我终于想通了。我的错误在于引用的从属 属性 名称。而不是 SlavePositionId
我应该放 MasterPositionId
.
这是有道理的,因为 Position 实体充当主 table 并且在现实世界中外键关系是在细节 table 上建立的,而不是主实体。由于从属实体中没有 属性 与主实体中的 PK 同名,并且有多个属性具有指向同一主实体的外键,因此 EF 需要更多 information.By 指定ForeignKey("MasterPositionId")
到 ICollection 导航 属性,我指示 EF Dependent 端点 属性 应被视为 MasterPositionId。所以我改变了这个
[ForeignKey("SlavePositionId")]
public virtual ICollection<SlavePosition> SlavePositions { get; set; }
至此
[ForeignKey("MasterPositionId")]
public virtual ICollection<SlavePosition> SlavePositions { get; set; }
其实前者本身也没有错,只是不适合这种情况。但是,如果我想要一个 MasterPositions
的集合,这将非常适合。
我有两个实体:
//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 行的详细信息 table。我可以通过 运行 下面的代码来确认这一点:
IEnumerable<SlavePositions> slavePositions= dbcontext.SlavePositions.Where(x=>x.MasterPositionId==1);
我得到五个 SlavePosition。
此集合的正确属性应该是什么 属性?
我终于想通了。我的错误在于引用的从属 属性 名称。而不是 SlavePositionId
我应该放 MasterPositionId
.
这是有道理的,因为 Position 实体充当主 table 并且在现实世界中外键关系是在细节 table 上建立的,而不是主实体。由于从属实体中没有 属性 与主实体中的 PK 同名,并且有多个属性具有指向同一主实体的外键,因此 EF 需要更多 information.By 指定ForeignKey("MasterPositionId")
到 ICollection 导航 属性,我指示 EF Dependent 端点 属性 应被视为 MasterPositionId。所以我改变了这个
[ForeignKey("SlavePositionId")]
public virtual ICollection<SlavePosition> SlavePositions { get; set; }
至此
[ForeignKey("MasterPositionId")]
public virtual ICollection<SlavePosition> SlavePositions { get; set; }
其实前者本身也没有错,只是不适合这种情况。但是,如果我想要一个 MasterPositions
的集合,这将非常适合。