实体框架代码优先:处理来自同一表的两个外键
在使用实体框架代码优先建模实体之间的关系时,你可能会遇到需要建立来自同一表的两个外键的情况。这对于初学者来说尤其具有挑战性。
假设你想要为队伍和比赛创建数据模型,每场比赛都涉及两支队伍(主队和客队)。使用代码优先,你可能会编写以下代码:
<code class="language-csharp">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; } }</code>
然而,这段代码会引发异常:
此引用关系将导致不允许的循环引用。[约束名称 = Match_GuestTeam]
为了解决这个问题,你需要为 EF 提供不同的方式来映射外键。一个有效的解决方案是在 Team
类中为主场比赛和客场比赛创建单独的集合:
<code class="language-csharp">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; } }</code>
在 Match
类中,你可以移除 ForeignKey
属性,只需定义外键属性:
<code class="language-csharp">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; } }</code>
最后,在 DbContext
类中,你需要使用 HasRequired()
和 WithMany()
配置关系:
<code class="language-csharp">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); }</code>
通过这些更改,你就可以在实体框架代码优先模型中成功建立来自同一表的两个外键了。
以上是如何首先从实体框架代码中的同一表中处理两个外键?的详细内容。更多信息请关注PHP中文网其他相关文章!