我有两个表,它们有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应该不是问题吗?
答案 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记录。