【发布时间】:2021-05-24 10:16:15
【问题描述】:
我在我们的 ASP.NET MVC 项目中使用 Entity Framework 6.2.0,并且在其中一个操作中,我们使用以下代码从存储库中删除了一系列记录。我们希望这发生在事务范围内,因此发生任何错误都会回滚整个事务。
下面是我的代码 sn-p。如果我删除事务范围但失败,则以下代码可以正常工作。我们在这里使用数据库优先的方法。
using (var tScope = new TransactionScope(TransactionScopeOption.Required))
{
var boxes= _boxRepository.GetConditionalQuery(s => processId==1).ToList();
if (boxes.Count > 0)
_boxRepository.RemoveRange(boxes);
var boxDeliveries= _deliveriesepository.GetConditionalQuery(s => processId==1).ToList();
_boxDeliveryRepository.RemoveRange(boxDeliveries);
_unitOfWork.Commit();
tScope.Complete();
}
提前致谢。
【问题讨论】:
-
你所说的“失败”是什么意思?你有什么例外吗?
-
@AirCodeOne 没有
RemoveRanges。不需要与 EF 或 NHibernate 进行事务。您使用的“存储库”代码破坏了 EF。我们无法告诉您如何修复未发布的代码,但真正的解决方案是简单地删除“通用存储库”代码。仔细阅读There is no need for Unit of Work or Repository with Entity Framework -
一个 DbContext 已经是一个工作单元,一个 DbSet 已经是一个存储库。 DbContext 持久化所有更改,并且仅连接到数据库以加载数据或使用
SaveChanges持久化更改。当您调用SaveChanges时,它会保留 all 未决更改,而不仅仅是最后一个。您可能需要使用显式事务的唯一原因是您在高级 DbContext 之上放置了一个低级“存储库”接口,在每个操作之后执行SaveChanges。这破坏了工作单元,所以现在你需要一个额外的事务来恢复它 -
@AirCodeOne 没有“如果有效”。如果使用得当,EF 可以工作。为什么您认为没有文档教程使用“存储库”模式?微软不知道吗? MS 已经发布模式指南 20 年了,甚至在它变得不必要之前提供了 repo 实现。为什么有这么多关于 "repository" 引发的问题的 EF 相关问题?通用存储库和 ORM 是圆孔的方形钉
-
@AirCodeOne 这也不是什么新鲜事 Repository is the new Singleton 写于 2009 年。不幸的是,一些“样板”框架和懒惰的作者只是简单地复制粘贴 Java 技术,所以他们可以说它们涵盖了“最佳实践”。通用 repo 所做的不仅仅是破坏 UoW - 它破坏了 DbContext 的断开连接操作和乐观并发,强制执行长期事务,导致阻塞和死锁。通过使用它,您回到了 1999 年,当时引入了断开连接的记录集
标签: c# mysql entity-framework repository-pattern transactionscope