Dot-Net
引入 FOREIGN KEY 約束可能會導致循環或多個級 聯路徑 - 為什麼?
我已經為此苦苦掙扎了一段時間,無法完全弄清楚發生了什麼。我有一個卡片實體,其中包含邊(通常是 2 個)-卡片和邊都有一個階段。我正在使用 EF Codefirst 遷移,遷移失敗並出現以下錯誤:
在表“Sides”上引入 FOREIGN KEY 約束“FK_dbo.Sides_dbo.Cards_CardId”可能會導致循環或多個級聯路徑。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 約束。
這是我的Card實體:
public class Card { public Card() { Sides = new Collection<Side>(); Stage = Stage.ONE; } [Key] [Required] public virtual int CardId { get; set; } [Required] public virtual Stage Stage { get; set; } [Required] [ForeignKey("CardId")] public virtual ICollection<Side> Sides { get; set; } }這是我的Side實體:
public class Side { public Side() { Stage = Stage.ONE; } [Key] [Required] public virtual int SideId { get; set; } [Required] public virtual Stage Stage { get; set; } [Required] public int CardId { get; set; } [ForeignKey("CardId")] public virtual Card Card { get; set; } }這是我的舞台實體:
public class Stage { // Zero public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE"); // Ten seconds public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO"); public static IEnumerable<Stage> Values { get { yield return ONE; yield return TWO; } } public int StageId { get; set; } private readonly TimeSpan span; public string Title { get; set; } Stage(TimeSpan span, string title) { this.span = span; this.Title = title; } public TimeSpan Span { get { return span; } } }奇怪的是,如果我在我的 Stage 類中添加以下內容:
public int? SideId { get; set; } [ForeignKey("SideId")] public virtual Side Side { get; set; }遷移成功執行。如果我打開 SSMS 並查看表格,我可以看到
Stage_StageId已添加到Cards(如預期/期望),但Sides不包含對Stage(未預期)的引用。如果我再添加
[Required] [ForeignKey("StageId")] public virtual Stage Stage { get; set; } public int StageId { get; set; }在我的 Side 課程中,我看到
StageId我的表中添加了Side列。這是有效的,但現在在我的整個應用程序中,任何對
Stage包含 a 的引用SideId,在某些情況下是完全不相關的。 如果可能的話,我只想給我Card和Side實體一個Stage基於上述 Stage 類的屬性,而不用引用屬性污染舞台類……我做錯了什麼?
因為
Stage是required,所以所有涉及的一對多關係Stage都將預設啟用級聯刪除。這意味著,如果您刪除一個Stage實體
- 刪除將直接級聯到
Side- 刪除將直接級聯到
Card並且因為Card並且Side與預設啟用的級聯刪除具有必需的一對多關係,然後它將級聯Card到Side
Stage因此,您有兩個從to的級聯刪除路徑Side- 這會導致異常。您必須
Stage在至少一個實體中設置可選(即[Required]從屬性中刪除Stage屬性)或使用 Fluent API 禁用級聯刪除(數據註釋不可能):modelBuilder.Entity<Card>() .HasRequired(c => c.Stage) .WithMany() .WillCascadeOnDelete(false); modelBuilder.Entity<Side>() .HasRequired(s => s.Stage) .WithMany() .WillCascadeOnDelete(false);