让我假装我有三个表,每个表都有一个名为Id
的主键:
TableA
------
Id
TableB
------
Id
TableC
-----
Id
意图是每个实体彼此具有一对一的导航属性,以便我可以在给定任何实体的任何方向上导航。很遗憾,我还没有找到[Key]
,[ForeignKey]
和导航属性的组合,每个实体允许此多次。
例如,这有效(实体框架认为TableA
是1:1关系中的主体):
public class TableA
{
[Key]
[Required]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
public virtual TableC TableB { get; set; }
}
public class TableB
{
[Key]
[ForeignKey("TableA")]
[Required]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
}
但这不起作用:
public class TableB
{
[Key]
[ForeignKey("TableA,TableC")] // The constructor documentation says this will work, but at runtime it throws an exception
[Required]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
public virtual TableC TableC { get; set; }
}
也不是这样:
public class TableB
{
[Key]
[Required]
public Guid Id { get; set; }
[ForeignKey("Id")]
public virtual TableA TableA { get; set; }
[ForeignKey("Id")]
public virtual TableC TableC { get; set; }
}
如何使用属性来允许这些关系?目前,如果我想从TableC
导航到TableB
,我必须浏览TableA
,导致额外的不必要的数据库查找。似乎实体框架想要强制一种可能没有的层次关系。
答案 0 :(得分:1)
我认为你需要的是这样的模型:
public class TableA
{
[Key]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
public virtual TableC TableC { get; set; }
}
public class TableB
{
[Key]
[ForeignKey("TableA")]
public Guid Id { get; set; }
public virtual TableA TableA { get; set; }
public virtual TableC TableC { get; set; }
}
public class TableC
{
[Key]
[ForeignKey("TableB")]
public Guid Id { get; set; }
public virtual TableB TableB { get; set; }
[Required]
public virtual TableA TableA { get; set; }
}
您不需要在TableC
实体中为TableB
导航属性指定FK属性,因为TableB
是B和C之间关系的主体。
尝试删除Required
数据注释并以这种方式配置关系,覆盖上下文中的OnModelCreating
方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TableA>().HasOptional(a => a.TableC).WithOptionalPrincipal(c => c.TableA);
base.OnModelCreating(modelBuilder);
}