为了账号安全,请及时绑定邮箱和手机立即绑定

引入外键约束可能会导致循环或多个级联路径-为什么?

引入外键约束可能会导致循环或多个级联路径-为什么?

慕田峪9158850 2019-06-23 16:58:45
引入外键约束可能会导致循环或多个级联路径-为什么?我和这件事斗争了一段时间了,我不太明白到底发生了什么事。我有一个卡片实体,其中包含侧(通常2)-和卡片和两边都有一个舞台。我使用的是EF CodeFirst迁移,但是这个错误导致迁移失败:在表“侧”上引入外键约束‘fk_dbo.ides_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; }}这是我的侧实体: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; }迁移成功运行。如果我打开SSM,看看这些表,我可以看到Stage_StageId已添加到Cards(如预期/所需)Sides不包含引用Stage(未预期)。如果我再加上    [Required]     [ForeignKey("StageId")]     public virtual Stage Stage { get; set; }     public int StageId { get; set; }到我的旁听课上,我明白了StageId列添加到我的Side桌子。这是可行的,但现在我的整个应用程序中,任何引用Stage包含SideId在某些情况下是完全不相关的。我只想把我的Card和Side实体aStage属性,如果可能的话,在不污染带有引用属性的Stage类的情况下,..我做错什么了?
查看完整描述

3 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

因为Stage所需,所有一对多的关系Stage默认情况下,将启用级联删除。意思是,如果删除Stage实体

  • 删除将直接级联到

    Side

  • 删除将直接级联到

    Card

    因为

    Card

    Side

    在默认情况下启用级联删除所需的一对多关系,然后它将从

    Card

    Side

因此,您有两个级联删除路径。StageSide-这就导致了例外。

你必须要么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);


查看完整回答
反对 回复 2019-06-23
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

我有一张桌子,它和其他人有着循环的关系,而我也得到了同样的错误。原来是关于不可空的外键的。如果键不可空,则相关对象必须删除,循环关系不允许这样做。所以使用可空外键。

[ForeignKey("StageId")]public virtual Stage Stage { get; set; }public int? StageId { get; set; }


查看完整回答
反对 回复 2019-06-23
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

想知道如何在EF核心中这样做的人:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
                {
                    relationship.DeleteBehavior = DeleteBehavior.Restrict;
                }
           ..... rest of the code.....


查看完整回答
反对 回复 2019-06-23
  • 3 回答
  • 0 关注
  • 595 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信