2014-11-07 6 views
3

Сначала я разрабатываю приложение с использованием кода Entity-Framework и миграции.Entity Framework Несколько каскадных удалений

У меня есть следующий класс, представляющий отношение между двумя пользователями, когда один пользователь делает резервную копию другого для некоторого продукта. Классы пользователей и продуктов не имеют ссылок на 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; } 
} 

Я переопределить 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")); 
} 

Файл миграции, который был создан после того, как "Add-Migration" команда применяется, содержит следующий код.

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

Однако, когда я запустить приложение, я получаю следующее исключение:

Вводя ограничение FOREIGN KEY «FK_dbo.UserBackup_dbo.User_BackupUserId» на столе «UsersBackup» может вызвать циклы или несколько путей порогов.

Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY.

Не удалось создать ограничение. См. Предыдущие ошибки.

Если я удаляю ограничение внешнего ключа, я не получаю ошибку. Или, по крайней мере, укажите «cascadeDelete: false». Но мне нужно, чтобы запись была удалена из таблицы UserBackup в случае удаления пользователя Backup.

+0

Прочитайте мой ответ на это [StackOverflow должность] (HTTP: // StackOverflow. com/questions/26729822/entity-framework-relationship/26730485 # 26730485) –

ответ

4

Это ограничение SQL Server not Entity Framework. В SQL Server у вас не может быть 2 внешних ключа с каскадным удалением в одну и ту же таблицу (UserId и BackupUserId указывают на ту же таблицу).

Я спросил людей в MS об этом в 2009 году, и ответ был на это ограничение не будет удалено. Теперь в 2014 году это не изменилось, поэтому я предполагаю, что они серьезно относились к этому.

Ваш единственный вариант - вручную удалить удаление и удалить параметр каскада.

Edit:

Чтобы удалить каскад просто добавить .WillCascadeOnDelete(false); для каждого отношения или повернуть каскадные от для всей модели:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
+0

Спасибо, я думал, что сошел с ума, потому что не мог понять, что случилось. – Runaground

Смежные вопросы