我已经为这个问题纠结了一段时间,不太明白发生了什么。我有一个卡片实体,它包含边(通常是2)-卡片和边都有一个阶段。我使用EF Codefirst迁移和迁移失败与此错误:

引入外键约束'FK_dbo.Sides_dbo。Cards_CardId” 表'Sides'可能会导致循环或多个级联路径。指定 DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键 约束。

这是我的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的引用都包含一个SideId,这在某些情况下是完全不相关的。我想给我的卡和边实体一个基于上面的Stage类的Stage属性,如果可能的话,不要用引用属性污染Stage类……我做错了什么?


当前回答

当我从EF7模型迁移到EF6版本时,我得到了很多实体的这个错误。我不想一次逐个查看每个实体,所以我使用:

builder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
builder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

其他回答

我有一个与其他表有循环关系的表,我得到了同样的错误。结果是关于外键,它不是空的。如果键不是空的,则必须删除相关对象,而循环关系不允许这样做。使用可空外键。

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

可以将cascadeDelete设置为false或true(在migration Up()方法中)。这取决于你的需求。

AddForeignKey("dbo.Stories", "StatusId", "dbo.Status", "StatusID", cascadeDelete: false);

上述的解决方案对我都不起作用。我必须做的是在不需要的外键上使用一个可空的int (int?)(或者不是一个非空列键),然后删除我的一些迁移。

首先删除迁移,然后尝试可空int。

问题是修改和模型设计。不需要修改代码。

这听起来很奇怪,我不知道为什么,但在我的情况下,这是因为我的ConnectionString在“数据源”属性中使用了“。”。一旦我把它改为“localhost”,它就像一个魅力。不需要其他改变。

我也遇到了同样的问题,而且卡了很长时间。下面的步骤拯救了我。 遍历约束并将onDelete ReferentialAction从Cascade更改为NoAction

  constraints: table =>
  {
      table.PrimaryKey("PK_table1", x => x.Id);
      table.ForeignKey(
         name: "FK_table1_table2_table2Id",
         column: x => x.table2Id,
         principalTable: "table2",
         principalColumn: "Id",
         onDelete: ReferentialAction.NoAction);
  });