猿问

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

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

我和这件事斗争了一段时间了,我不太明白到底发生了什么事。我有一个卡片实体,其中包含侧(通常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在某些情况下是完全不相关的。我只想把我的CardSide实体aStage属性,如果可能的话,在不污染带有引用属性的Stage类的情况下,..我做错什么了?


慕田峪9158850
浏览 596回答 3
3回答

慕码人2483693

因为Stage是所需,所有一对多的关系Stage默认情况下,将启用级联删除。意思是,如果删除Stage实体删除将直接级联到Side删除将直接级联到Card因为Card和Side在默认情况下启用级联删除所需的一对多关系,然后它将从Card到Side因此,您有两个级联删除路径。Stage到Side-这就导致了例外。你必须要么Stage在至少一个实体中可选(即删除[Required]属性的Stage属性)或使用FLUENT API禁用级联删除(数据注释不可能):modelBuilder.Entity<Card>() &nbsp;&nbsp;&nbsp;&nbsp;.HasRequired(c&nbsp;=>&nbsp;c.Stage) &nbsp;&nbsp;&nbsp;&nbsp;.WithMany() &nbsp;&nbsp;&nbsp;&nbsp;.WillCascadeOnDelete(false);modelBuilder.Entity<Side>() &nbsp;&nbsp;&nbsp;&nbsp;.HasRequired(s&nbsp;=>&nbsp;s.Stage) &nbsp;&nbsp;&nbsp;&nbsp;.WithMany() &nbsp;&nbsp;&nbsp;&nbsp;.WillCascadeOnDelete(false);

一只名叫tom的猫

我有一张桌子,它和其他人有着循环的关系,而我也得到了同样的错误。原来是关于不可空的外键的。如果键不可空,则相关对象必须删除,循环关系不允许这样做。所以使用可空外键。[ForeignKey("StageId")]public&nbsp;virtual&nbsp;Stage&nbsp;Stage&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}public&nbsp;int?&nbsp;StageId&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}

牛魔王的故事

想知道如何在EF核心中这样做的人:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;override&nbsp;void&nbsp;OnModelCreating(ModelBuilder&nbsp;modelBuilder) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;relationship&nbsp;in&nbsp;modelBuilder.Model.GetEntityTypes().SelectMany(e&nbsp;=>&nbsp;e.GetForeignKeys())) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;relationship.DeleteBehavior&nbsp;=&nbsp;DeleteBehavior.Restrict; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.....&nbsp;rest&nbsp;of&nbsp;the&nbsp;code.....
随时随地看视频慕课网APP
我要回答