Документация EntityFramework утверждает, что возможно следующее поведение:
Если внешний ключ зависимого объекта является нулевым, Code First делает не устанавливать каскадное удаление в отношении, а когда основной удаленный внешний ключ будет установлен на нуль.
(из http://msdn.microsoft.com/en-us/jj591620)
Однако я не могу добиться такого поведения.
У меня есть следующие Entities, определенные с помощью code-first:
public class TestMaster
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<TestChild> Children { get; set; }
}
public class TestChild
{
public int Id { get; set; }
public string Name { get; set; }
public virtual TestMaster Master { get; set; }
public int? MasterId { get; set; }
}
Вот конфигурация отображения Fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TestMaster>()
.HasMany(e => e.Children)
.WithOptional(p => p.Master).WillCascadeOnDelete(false);
modelBuilder.Entity<TestChild>()
.HasOptional(e => e.Master)
.WithMany(e => e.Children)
.HasForeignKey(e => e.MasterId).WillCascadeOnDelete(false);
}
Внешний ключ имеет значение NULL, свойство навигации отображается как Необязательно, поэтому я ожидаю, что каскадное удаление будет работать, как описано как MSDN, т.е. свести на нет MasterID всех дочерних элементов и затем удалить главный объект.
Но когда я действительно пытаюсь удалить, я получаю ошибку нарушения FK:
using (var dbContext = new TestContext())
{
var master = dbContext.Set<TestMaster>().Find(1);
dbContext.Set<TestMaster>().Remove(master);
dbContext.SaveChanges();
}
В SaveChanges() он выдает следующее:
System.Data.Entity.Infrastructure.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
----> System.Data.UpdateException : An error occurred while updating the entries. See the inner exception for details.
----> System.Data.SqlClient.SqlException : The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.TestChilds_dbo.TestMasters_MasterId". The conflict occurred in database "SCM_Test", table "dbo.TestChilds", column 'MasterId'.
The statement has been terminated.
Я делаю что-то неправильно или я неправильно понял, что говорит MSDN?