C# 如何同时从上下文中删除实体?

C# 如何同时从上下文中删除实体?,c#,entity-framework,concurrency,parallel-processing,dbcontext,C#,Entity Framework,Concurrency,Parallel Processing,Dbcontext,假设我们有一个要删除的实体列表: var items = this.itemRepository.GetRange(1, 1000).ToList(); 我不想简单地循环删除项目,而是希望像这样同时删除它们: items.AsParallel().ForAll(item => { this.itemRepository.Remove(item); }); this.UnitOfWork.Commit(); 您建议我如何像这样执行删

假设我们有一个要删除的实体列表:

var items = this.itemRepository.GetRange(1, 1000).ToList();
我不想简单地循环删除项目,而是希望像这样同时删除它们:

items.AsParallel().ForAll(item =>
        {
            this.itemRepository.Remove(item);
        });
this.UnitOfWork.Commit();

您建议我如何像这样执行删除?

EF上下文不是线程安全的,所以我不会这样做

如果您需要性能,请选择并行!=更快。并行代码允许您在同一时间做更多的事情,但您往往会发现,单个工作单元至少需要相同的时间,但有时由于上下文切换等原因需要更长的时间,只是您不是一次做5件事,而是一次做5件事。这将使您更有效地使用可用硬件,而不是性能,而是可扩展性和响应性。
从EF6开始,它为异步/等待支持公开了一个异步API,但这同样只允许对其执行一个并发操作。如果要执行多个异步读取,则每个读取操作都需要一个上下文-这将使数据库承担管理完整性的责任。

EF上下文不是线程安全的,因此我不会这样做

如果您需要性能,请选择并行!=更快。并行代码允许您在同一时间做更多的事情,但您往往会发现,单个工作单元至少需要相同的时间,但有时由于上下文切换等原因需要更长的时间,只是您不是一次做5件事,而是一次做5件事。这将使您更有效地使用可用硬件,而不是性能,而是可扩展性和响应性。
从EF6开始,它为异步/等待支持公开了一个异步API,但这同样只允许对其执行一个并发操作。如果要执行多个异步读取,则每个读取操作需要一个上下文-这将使数据库承担管理完整性的责任。

如果尚未使用EF6,则可以执行以下操作:

this.itemRepository.RemoveRange(items);

如果尚未使用EF6,请升级到EF6,然后可以执行以下操作:

this.itemRepository.RemoveRange(items);
EF6在DbSet中添加了RemoveRange方法

这比一次删除单个对象更有效,因为默认情况下,Entity Framework在Remove方法中调用DetectChanges,而RemoveRange只调用它一次

但是,当您调用SaveChanges时,EF仍然执行单个delete语句。在未来的版本中有一个新版本

参考资料:

EF6在DbSet中添加了RemoveRange方法

这比一次删除单个对象更有效,因为默认情况下,Entity Framework在Remove方法中调用DetectChanges,而RemoveRange只调用它一次

但是,当您调用SaveChanges时,EF仍然执行单个delete语句。在未来的版本中有一个新版本

参考资料:


EF上下文不是线程安全的,所以我不会这样做。此外,我无法立即看到此:并行!=更快。投票@Adamhuldsworth的评论不够多。那么,你为什么不把它写在答案里呢?这似乎是正确的。@Rezaoulliae根据请求我可以这样做,但从表面上看,如果您试图解决进一步的问题,我看不出这有多大价值。EF上下文不是线程安全的,所以我不会这样做。此外,我无法立即看到此:并行!=更快。投票@Adamhuldsworth的评论不够多。那么,你为什么不把它写在答案里呢?“这似乎是对的。”RezaOwliaei请求我可以做,但从表面上看,如果你真的试图解决进一步的问题,我看不出这有多大价值。