实体框架多个级联删除

Run*_*und 3 c# sql entity-framework ef-model-builder

我正在开发一个首先使用Entity-Framework代码和迁移的应用程序.

我有以下类,表示当一个用户为某个产品备份另一个用户时两个用户之间的关系.User和Product类没有对UserBackup的任何引用.此关系应映射到dbo.UserBackup表.用户可以为多个产品拥有多个备份用户.所以基本上只有ProductId,BackupUserId和UserId的组合在表中是唯一的.

public class UserBackup
{
    public int Id { get; set; }

    public User User { get; set; }

    public User BackupUser { get; set; }

    public Product Product { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我在上下文类中重写OnModelCreating方法,如下所示:

private static void CreateUserBackupTable(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<UserBackup>().ToTable("UserBackup");
    modelBuilder.Entity<UserBackup>().HasKey(e => e.Id);
    modelBuilder.Entity<UserBackup>().HasRequired<User>(e => e.User).WithMany().Map(x => x.MapKey("UserId"));
    modelBuilder.Entity<UserBackup>().HasRequired<User>(e => e.BackupUser).WithMany().Map(x => x.MapKey("BackupUserId"));
    modelBuilder.Entity<UserBackup>().HasRequired<Product>(e => e.Product).WithMany().Map(x => x.MapKey("ProductId"));
}
Run Code Online (Sandbox Code Playgroud)

应用"添加 - 迁移"命令后生成的迁移文件包含以下代码.

CreateTable(
    "dbo.UserBackup",
    c => new
    {
        Id = c.Int(nullable: false, identity: true),
        UserId = c.Int(nullable: false),
        BackupUserId = c.Int(nullable: false),
        ProductId = c.Int(nullable: false)
    })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.User", t => t.UserId, cascadeDelete: true)
    .ForeignKey("dbo.User", t => t.BackupUserId, cascadeDelete: true)
    .ForeignKey("dbo.Product", t => t.ProductId, cascadeDelete: true)
    .Index(t => t.UserId)
    .Index(t => t.BackupUserId)
    .Index(t => t.ProductId);
Run Code Online (Sandbox Code Playgroud)

但是,当我运行应用程序时,我得到以下异常:

在'UsersBackup'表上引入FOREIGN KEY约束'FK_dbo.UserBackup_dbo.User_BackupUserId'可能会导致循环或多个级联路径.

指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.

无法创建约束.查看以前的错误.

如果我删除外键约束,我不会得到错误.或者至少指定"cascadeDelete:false".但是,如果删除备份用户,我需要从UserBackup表中删除该记录.

too*_*too 5

这是SQL Server而非实体框架的限制.在SQL Server中,您不能将2个带有级联删除的外键复制到同一个表中(UserId和BackupUserId指向同一个表).

2009年,我向MS的人询问了这个问题,答案是这个限制不会被删除.现在在2014年它没有改变,所以我猜他们认真对待它.

您唯一的选择是手动管理删除并删除级联选项.

编辑:

要删除级联,只需.WillCascadeOnDelete(false);为每个关系添加或为整个模型关闭级联:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
Run Code Online (Sandbox Code Playgroud)