如何清除()Entity Framework ICollection 中的所有元素?

How to Clear() all elements from Entity Framework ICollection?

我在使用 Clear()

从 entity framework 中的 collection 中删除所有元素时遇到问题

考虑博客和帖子中经常使用的示例。

public class Blog
{
    public int Id {get; set;}
    public string Name {get; set;}
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }

    // foreign key to Blog:
    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; }

    public string Title { get; set; }
    public string Text { get; set; }
}

public class BlogContext : DbContext
{
    public DbSet<Blog> Blogs {get; set;}
    public DbSet<Post> Posts {get; set;}
}

一个博客有很多帖子。一个博客有一个 ICollection of Posts。博客和帖子之间存在直接的 one-to-many 关系。

假设我想删除博客中的所有帖子

当然我可以做到以下几点:

Blog myBlog = ...
var postsToRemove = dbContext.Posts.Where(post => post.BlogId == myBlog.Id);
dbContext.RemoveRange(postsToRemove);
dbContext.SaveChanges();

然而,以下似乎更容易:

Blog myBlog = ...
myBlog.Posts.Clear();
dbContext.SaveChanges();

但是这会导致 InvalidOperationException:

操作失败:无法更改关系,因为一个或多个 foreign-key 属性是 non-nullable。当对关系进行更改时,相关的 foreign-key 属性 将设置为空值。如果 foreign-key 不支持空值,则必须定义新关系,必须为 foreign-key 属性 分配另一个 non-null 值,或者不相关的 object必须删除。

清除 collection 的正确方法是什么?有没有流利的API声明?

您的两个代码示例之间存在差异。

您的第一个代码示例 dbContext.RemoveRange(postsToRemove) 删除了 Post 条记录。因此,涉及这些记录的任何关系也将被删除。

在您的第二个代码示例 myBlog.Posts.Clear() 中,您将删除 myBlog 与其对应的 Post 记录之间的关系。 'real' 底层操作是将 Post 记录的 BlogId 的值设置为 null。不幸的是,这是不可能的,因为 BlogId 设置为不可为空。所以,简而言之,删除了关系,实际上没有删除任何记录。

Clear 处理关系而不是删除实体。

在您编写的两个解决方案之间有一个可行的(我认为更具可读性)中间解决方案。

dbContext.Posts.RemoveRange(myBlog.Posts);
// Now (also before SaveChanges) the myBlog.Posts is empty
dbContext.SaveChanges();

编辑
RemoveRange 还从 Blog.Posts 集合中删除帖子