entity-framework - 引入外键约束的.NET 可能导致循环或者多重级联路径?

  显示原文与译文双语对照的内容

我一直在跟踪这个过程,并不能明确发现什么发生了。 我有一个卡片实体,其中包含( 通常 2 ) - 和两个卡片和侧面有一个阶段。 我正在使用 EF Codefirst迁移,迁移会因这里错误而失败:

在表'侧面'上引入外键约束'fk_dbo.sides_dbo.cards_cardid'可能导致循环或者多个层叠。 在不删除操作或者更新没有操作时指定,或者修改其他外键约束。

以下是我的实体:


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; } }


}



奇怪的是,如果我将以下内容添加到我的舞台类别中:


 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; }



在我的侧部类中,我看到 StageId 列添加到 Side 表中。

这是工作,但在我的应用程序中,任何对 Stage的引用都包含一个 SideId,在某些情况。 如果可能的话,我希望为 CardSide 实体提供基于上述阶段类的Stage 属性,而不会使用引用属性污染舞台类( 如果可能的话。 我做错什么了?

时间: 原作者:

因为 Stage 是必需所有one-to-many相关的关系都将在默认情况下启用级联删除。 这意味着如果你删除一个 Stage 实体

  • 删除将直接级联到 Side
  • delete将直接级联到 Card,因为 CardSide 在默认情况下与级联删除启用了one-to-many关系,然后将从 Card 级联到 Side

因此,从 StageSide 有两个级联删除路径,这会导致异常。

你必须在至少一个实体中选择 Stage ( 例如 。 从 Stage 属性中删除 [Required] 属性) 或者使用 Fluent ( 。使用数据注释不可能) 禁用级联删除:


modelBuilder.Entity<Card>()


. HasRequired(c => c.Stage)


. WithMany()


. WillCascadeOnDelete(false);



modelBuilder.Entity<Side>()


. HasRequired(s => s.Stage)


. WithMany()


. WillCascadeOnDelete(false);



原作者:
...