简体   繁体   English

实体框架多个级联删除

[英]Entity Framework Multiple Cascading Deletes

I'm developing an application using Entity-Framework code first and migrations. 我正在开发一个首先使用Entity-Framework代码和迁移的应用程序。

I have the following class, representing relation between two users when one user makes backup of another one for some product. 我有以下类,表示当一个用户为某个产品备份另一个用户时两个用户之间的关系。 User and Product classes don't have any references to UserBackup. User和Product类没有对UserBackup的任何引用。 This relation should map to dbo.UserBackup table. 此关系应映射到dbo.UserBackup表。 User can have multiple Backup Users for multiple products. 用户可以为多个产品拥有多个备份用户。 So basically only the combination of ProductId, BackupUserId and UserId is unique in the table. 所以基本上只有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; }
}

I override OnModelCreating method within context class like this: 我在上下文类中重写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"));
}

The migration file, which was generated after "Add-Migration" command is applied, contains the following code. 应用“添加 - 迁移”命令后生成的迁移文件包含以下代码。

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);

However, when I run the application I get the following exception: 但是,当我运行应用程序时,我得到以下异常:

Introducing FOREIGN KEY constraint 'FK_dbo.UserBackup_dbo.User_BackupUserId' on table 'UsersBackup' may cause cycles or multiple cascade paths. 在'UsersBackup'表上引入FOREIGN KEY约束'FK_dbo.UserBackup_dbo.User_BackupUserId'可能会导致循环或多个级联路径。

Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

Could not create constraint. 无法创建约束。 See previous errors. 查看以前的错误。

If I remove the foreign key constraint, I don't get the error. 如果我删除外键约束,我不会得到错误。 Or at least specify " cascadeDelete: false". 或者至少指定“cascadeDelete:false”。 But I need the record to be deleted from UserBackup table in case when Backup user is deleted. 但是,如果删除备份用户,我需要从UserBackup表中删除记录。

This is a limitation of SQL Server not Entity Framework. 这是SQL Server而非实体框架的限制。 In SQL Server you can't have 2 foreign keys with cascade delete to the same table (UserId and BackupUserId point to the same table). 在SQL Server中,您不能将2个带有级联删除的外键复制到同一个表中(UserId和BackupUserId指向同一个表)。

I asked people at MS about it in 2009 and the answer was this limitation won't be removed. 2009年,我向MS的人询问了这个问题,答案是这个限制不会被删除。 Now in 2014 it did not change so I guess they were serious about it. 现在在2014年它没有改变所以我猜他们认真对待它。

Your only option is to manually manage deletion and remove cascade option. 您唯一的选择是手动管理删除并删除级联选项。

Edit: 编辑:

To remove cascade just add .WillCascadeOnDelete(false); 要删除级联,只需添加.WillCascadeOnDelete(false); for each relation or turn cascading off for a whole model: 对于每个关系或转向整个模型的级联:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM