實體框架代碼優先:處理來自同一表的兩個外鍵
在使用實體框架代碼優先建模實體之間的關係時,你可能會遇到需要建立來自同一表的兩個外鍵的情況。這對於初學者來說尤其具有挑戰性。
假設你想要為隊伍和比賽創建數據模型,每場比賽都涉及兩支隊伍(主隊和客隊)。使用代碼優先,你可能會編寫以下代碼:
<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中文網其他相關文章!