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

本文关键字:管我 CascadeOnDelete ID 外键 | 更新日期: 2023-09-27 18:11:21

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

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

注意,primary_id是一个非空列,这也是为什么我将关系设置为.WithRequired() -一个MyOther需要有一个MyPrimary,不能单独存在。

现在我有以下代码:

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

我收到以下异常:

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

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

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

当您调用.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记录。