entity framework代码来自同一个表的前两个外键

我刚刚开始使用EF代码,所以我完全是这个主题的初学者。

我想创build球队和比赛之间的关系:1比赛= 2队(主场,客队)和结果。 我认为创build这样的模型很容易,所以我开始编码:

public class Team { [Key] public int TeamId { get; set;} public string Name { get; set; } public virtual ICollection<Match> Matches { get; set; } } public class Match { [Key] public int MatchId { get; set; } [ForeignKey("HomeTeam"), Column(Order = 0)] public int HomeTeamId { get; set; } [ForeignKey("GuestTeam"), Column(Order = 1)] public int GuestTeamId { get; set; } public float HomePoints { get; set; } public float GuestPoints { get; set; } public DateTime Date { get; set; } public virtual Team HomeTeam { get; set; } public virtual Team GuestTeam { get; set; } } 

我得到一个例外:

参照关系将导致不允许的循环引用。 [约束名称= Match_GuestTeam]

我怎样才能创build这样的模型,2个外键到同一个表? TIA。

尝试这个:

 public class Team { public int TeamId { get; set;} public string Name { get; set; } public virtual ICollection<Match> HomeMatches { get; set; } public virtual ICollection<Match> AwayMatches { get; set; } } public class Match { public int MatchId { get; set; } public int HomeTeamId { get; set; } public int GuestTeamId { get; set; } public float HomePoints { get; set; } public float GuestPoints { get; set; } public DateTime Date { get; set; } public virtual Team HomeTeam { get; set; } public virtual Team GuestTeam { get; set; } } public class Context : DbContext { ... protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Match>() .HasRequired(m => m.HomeTeam) .WithMany(t => t.HomeMatches) .HasForeignKey(m => m.HomeTeamId) .WillCascadeOnDelete(false); modelBuilder.Entity<Match>() .HasRequired(m => m.GuestTeam) .WithMany(t => t.AwayMatches) .HasForeignKey(m => m.GuestTeamId) .WillCascadeOnDelete(false); } } 

主键按默认约定进行映射。 队必须有两个比赛的集合。 您不能有两个FK引用的单个集合。 匹配没有级联删除映射,因为它不能在这些自引用多对多的工作。

也可以在导航属性中指定ForeignKey()属性:

 [ForeignKey("HomeTeamID")] public virtual Team HomeTeam { get; set; } [ForeignKey("GuestTeamID")] public virtual Team GuestTeam { get; set; } 

这样你不需要添加任何代码到OnModelCreate方法

我知道这是一个几年以前的职位,你可以用上面的解决scheme解决你的问题。 但是,我只是想build议使用InverseProperty的人仍然需要。 至less你不需要在OnModelCreating中改变任何东西。

下面的代码是未经testing的。

 public class Team { [Key] public int TeamId { get; set;} public string Name { get; set; } [InverseProperty("HomeTeam")] public virtual ICollection<Match> HomeMatches { get; set; } [InverseProperty("GuestTeam")] public virtual ICollection<Match> GuestMatches { get; set; } } public class Match { [Key] public int MatchId { get; set; } public float HomePoints { get; set; } public float GuestPoints { get; set; } public DateTime Date { get; set; } public virtual Team HomeTeam { get; set; } public virtual Team GuestTeam { get; set; } } 

您可以在MSDN上阅读有关InverseProperty的更多信息: https ://msdn.microsoft.com/en-us/data/jj591583?f = 255 & MSPPError = -2147217396#Relationships

你也可以试试这个:

 public class Match { [Key] public int MatchId { get; set; } [ForeignKey("HomeTeam"), Column(Order = 0)] public int? HomeTeamId { get; set; } [ForeignKey("GuestTeam"), Column(Order = 1)] public int? GuestTeamId { get; set; } public float HomePoints { get; set; } public float GuestPoints { get; set; } public DateTime Date { get; set; } public virtual Team HomeTeam { get; set; } public virtual Team GuestTeam { get; set; } } 

当你让一个FK列允许NULLS,你打破了这个循环。 或者我们只是在欺骗EF模式生成器。

在我的情况下,这个简单的修改解决了这个问题。

这是因为级联删除是默认启用的。 问题是当你在实体上调用一个删除时,它也会删除每个f-key引用的实体。 您不应该使“必需”的值为空来解决这个问题。 更好的select是删除EF Code First的级联删除约定:

 modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

在映射/configuration时明确指出何时为每个子级执行级联删除可能更安全。 该实体。