EF Core 3 的 DbContextScope 模式

Posted

技术标签:

【中文标题】EF Core 3 的 DbContextScope 模式【英文标题】:DbContextScope Pattern for EF Core 3 【发布时间】:2020-04-21 05:00:35 【问题描述】:

你们中的一些人可能熟悉DbContextScope library,它允许您在代码中嵌套范围,并允许这些范围共享一个公共 DbContext。这个想法是 DbContext 由作用域库为您管理,而不是在上下文上调用 SaveChanges(),而是在作用域上调用 SaveChanges()。之所以神奇,是因为作用域只会在最外层调用 SaveChanges() 时保存上下文中的所有更改,因此在 DbContext 上执行的所有嵌套操作都会保存在外部作用域级别的单个事务中。

既然 DI 是 .NET Core 中的一等公民,看来作用域也成为了 .NET Core 生态系统的重要组成部分,而 EF Core 团队知道这一点,已经在允许 DbContexts 的基础上实现了作用域由 DI 系统注入,并且(我假设)允许在范围级别进行更改保存,而不是以某种方式直接在 DbContexts 上进行。

所以我的问题是:

通过范围共享 DbContext 的适当方法是什么,允许在范围级别而不是通常在 DbContext 上调用 SaveChanges() 的代码级别管理 SaveChanges()? EF Core 中是否有新机制可以为您管理这个问题,就像 DbContextScope 作为第 3 方库为您做的那样? 别闹了,别再讲你为什么认为除了 EF 还需要实施 UOW 的讲座。 K thnxs 再见。

更新:截至 2020 年 6 月,有多个 DbContextScope 分支可与 EF Core 3 配合使用。

更新:这个项目的分叉可以在这里查看:https://github.com/mehdime/DbContextScope/network

有几个 EF Core 3 版本...我还没有尝试过,但是你去吧。

【问题讨论】:

我认为您可以放心地坚持使用 DbContextScope。 AmbientContext(它遵循的设计模式)在这里是一个合适的解决方案,就像它对于 TransactionScope 一样。 @Rafe - 回复:“有几个 DbContextScope 分支可与 EF Core 3 一起使用”:您能否分享指向哪些分支表示支持的链接?谢谢。 @DerekBromenshenkel 请参阅上面的第二次更新。 @Rafe 您正在使用哪些分支与 EF Core 3 配合使用? @guaike 老实说,我还没有升级。我很想知道是否有人使用过其中一个 EF Core 3 分支。 【参考方案1】:

从 Entity Framework 5.0.0 开始,there is IDbContextFactory<TDbContext> 让您可以控制 DbContexts 的创建和处置 (!!)。

您现在可以分别使用AddDbContextFactoryAddPooledDbContextFactory,而不是使用AddDbContextAddDbContextPool 注册您的DbContext。

请注意,此功能解决了DbContextScope 解决的一个问题,而不是所有问题。至于其他的问题和解决方法是什么,可以参考 Mehdi 的original post。很长,但很好。

【讨论】:

【参考方案2】:

DbContext 共享内置于 EF 的依赖注入设计中。

DI 容器将生成一个scoped DbContext instance for each web request。您可以从任何依赖它的组件共享 DbContext 实例,并调用 SaveChanges(),或在外部控制器中管理事务。

【讨论】:

所以你的建议是我将一个 DbContext 注入我的控制器并在那里调用保存更改???这听起来像是您想要管理数据操作的最糟糕的地方。这令人沮丧。 您可以随时随地管理 UoW。 DI 将为您处理 DbContext 生命周期。 那么范围功能中没有任何内容会自动为您调用保存更改? 问题在于,DbContext 在容器中可用这一事实并不能告诉您当前代码是否真正被感知的外部代码调用 其中,即会为您调用SaveChanges。使用 DbContextScope,只有在外部代码有意识地创建它时它才会出现,这意味着要么有人负责调用 SaveChanges,要么因为没有范围而出现异常。在我看来,常规范围的 DI 缺乏这一点,这使其不足。 @David Browne - DbContextScope 模式的重点是允许您显式控制 DbContext(s) 的生命周期。例如,在单个 Web 请求中,您可以有两个业务事务,每个事务都有一个单独的 DbContextScope。如果我错了,请纠正我,但大概没有办法使用 .NET Core 的内置依赖注入框架来获得这种级别的控制?

以上是关于EF Core 3 的 DbContextScope 模式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Devart.MySql 将 EF6 升级到 EF Core 3

EF Core 快速上手——EF Core 入门

sqlite + .net core ef 3

EF Core 3 的 DbContextScope 模式

EF Core多对多查询加入3个表

ef core 子对象集合插入顺序