我已经为这个问题纠结了一段时间,不太明白发生了什么。我有一个卡片实体,它包含边(通常是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类……我做错了什么?


当前回答

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

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

其他回答

使你的外键属性为空。这是可行的。

简单的方法是,将您的迁移文件(cascadeDelete: true)编辑为(cascadeDelete: false),然后在您的包管理器控制台中分配Update-Database命令。如果是你上次迁移的问题,那好吧。否则,检查您之前的迁移历史,复制这些内容,粘贴到您的最后一个迁移文件中,然后执行相同的操作。它非常适合我。

public partial class recommended_books : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.RecommendedBook",
            c => new
                {
                    RecommendedBookID = c.Int(nullable: false, identity: true),
                    CourseID = c.Int(nullable: false),
                    DepartmentID = c.Int(nullable: false),
                    Title = c.String(),
                    Author = c.String(),
                    PublicationDate = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.RecommendedBookID)
            .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: false) // was true on migration
            .ForeignKey("dbo.Department", t => t.DepartmentID, cascadeDelete: false) // was true on migration
            .Index(t => t.CourseID)
            .Index(t => t.DepartmentID);

    }

    public override void Down()
    {
        DropForeignKey("dbo.RecommendedBook", "DepartmentID", "dbo.Department");
        DropForeignKey("dbo.RecommendedBook", "CourseID", "dbo.Course");
        DropIndex("dbo.RecommendedBook", new[] { "DepartmentID" });
        DropIndex("dbo.RecommendedBook", new[] { "CourseID" });
        DropTable("dbo.RecommendedBook");
    }
}

当你的迁移失败时,你有几个选择: '引入外键约束'FK_dbo.RecommendedBook_dbo. '表“recommendations book”上的Department_DepartmentID'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。 无法创建约束或索引。见以前的错误。”

下面是一个使用“修改其他外键约束”的例子,在迁移文件中设置“cascadeDelete”为false,然后运行“update-database”。

在。net Core中,我将onDelete选项改为ReferencialAction。再

         constraints: table =>
            {
                table.PrimaryKey("PK_Schedule", x => x.Id);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_HomeId",
                    column: x => x.HomeId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_VisitorId",
                    column: x => x.VisitorId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
            });

在。net Core中,我玩了所有的上层答案-但没有任何成功。 我在数据库结构中做了很多更改,每次添加新的迁移尝试update-database,但收到相同的错误。

然后我开始逐个移除迁移,直到包管理器控制台抛出异常:

迁移'20170827183131_***'已经应用到数据库

之后,我成功添加了new migration (add-migration)和update-database

所以我的建议是:清除所有临时迁移,直到您当前的DB状态。