外键ID必须可以为空,尽管我有CascadeOnDelete

时间:2016-10-04 10:16:26

标签: c# entity-framework entity-framework-6

我有两个表,它们有1:n的关系。我使用了以下EF Code First关系定义:

modelBuilder.Entity<MyPrimary>()
            .HasMany(x => x.MyOthers)
            .WithRequired()
            .HasForeignKey(x => x.primary_id)
            .WillCascadeOnDelete();

请注意,primary_id是一个不可为空的列,这也是我将关系设置为.WithRequired()的原因 - MyOther需要拥有MyPrimary且不能独立存在。< / p>

现在我有以下代码:

myPrimary.MyOthers.Clear();
ctx.SaveChanges();

我收到以下例外:

  

System.InvalidOperationException:操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

为什么呢?不应该MyOther中的myPrimary.MyOthers个实例被级联删除,因此不可为空的FK应该不是问题吗?

1 个答案:

答案 0 :(得分:1)

当您致电.Clear() EF试图从MyPrimary取消分配MyOther时,想要删除MyOther记录并不够聪明。也许在明确之后,您将决定将这些MyOther记录添加到另一个MyPrimary记录中。所以你应该明确地将这些记录标记为已删除。您可以编写与此类似的方法

 public void MarkForDeleteItems<T>(ICollection<T> collection) where T : class
 {
     foreach (var collectionItem in collection.ToList())
     {
         ctx.Entry(collectionItem).State = EntityState.Deleted;
     }
 }

然后使用它

MarkForDeleteItems(myPrimary.MyOthers);
ctx.SaveChanges();

同样WillCascadeOnDelete意味着当您删除MyPrimary记录而不是数据库时,将删除与MyPrimary相关的所有MyOthers记录。