【问题标题】:How to Clear() all elements from Entity Framework ICollection?如何清除()实体框架 ICollection 中的所有元素?
【发布时间】:2017-02-13 13:48:32
【问题描述】:

我在使用 Clear() 从实体框架的集合中删除所有元素时遇到问题

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

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 的帖子。博客和帖子之间存在直接的一对多关系。

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

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

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:

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

清除收藏的正确方法是什么?对此是否有流畅的 API 语句?

【问题讨论】:

  • 据我所知,很遗憾,除了使用 .Remove().RemoveRange() 之外别无他法。当然,除了通过 EF 直接运行 SQL,但我认为这没有抓住重点。
  • 这里描述了您的案例:stackoverflow.com/a/6181060/6804888。似乎在不更改模型的情况下,您必须在将实体从集合中删除后手动删除它们。

标签: c# entity-framework icollection


【解决方案1】:

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

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

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

【讨论】:

  • 你是对的。我理解他们为什么选择这种方法。在某些示例中,当集合被清除时删除项目是不可取的。
【解决方案2】:

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

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

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

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

【讨论】:

  • 如果您真的想清除集合并删除所有元素(如问题中,此解决方案是最好的可读性。但是,如果您只有要创建其帖子的博客的 ID原始方法先保存检索博客
猜你喜欢
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多