AddDbContext 和 AddDbContextFactory 之间的区别

sun*_*iax 10 c# lifetime dbcontext entity-framework-core blazor

实际上我是从Blazor和开始的EF Core。在注册时DbContext我陷入困境。可以通过或 进行DbContext注册。但有什么区别呢?AddDbContextAddDbContextFactory

\n
builder.Services.AddDbContext<DataContext>(opt => opt.UseSqlServer("..."));\nbuilder.Services.AddDbContextFactory<DataContext>(opt => opt.UseSqlServer("..."));\n
Run Code Online (Sandbox Code Playgroud)\n

从文档我得到以下信息:

\n

AddDbContext

\n
\n

使用依赖注入时使用此方法...

\n
\n
\n

Entity Framework Core 不支持在同一 Microsoft.EntityFrameworkCore.DbContext 实例上运行多个并行操作。这包括异步查询的并行执行以及来自多个线程的任何显式并发使用。

\n
\n

AddDbContextFactory

\n
\n

建议为 Blazor 应用程序以及依赖项注入范围与上下文生命周期不一致的其他情况注册工厂...

\n
\n
\n

为了方便起见,此方法还将上下文类型本身注册为作用域服务。这允许上下文实例直接从依赖项注入范围解析或由工厂创建(视情况而定)。

\n
\n

因此,我们可以全局地说,如果程序需要DbContext从不同的线程访问,或者同时需要注册上下文,AddDbContextFactory因为当它被创建时(例如在控制器中),lifttime 被设置为作用域,所以我们每次得到一个新的DbContext

\n
private readonly DataContext _dbContext;\n\npublic BlogController(IDbContextFactory<DataContext> dbFactory)\n{\n  // Will be created as SCOPED DbContext?\n  _dbContext = dbFactory.CreateDbContext();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我还在这里发现了类似的问题。AddDbContext和中的生命周期AddDbContextFactory是在注册期间设置的。或者我\xc2\xb4m 缺少一些东西。

\n

所以我的问题一般是:

\n
    \n
  • AddDbContextFactory什么时候用AddDbContext?
  • \n
  • DbContext之间的寿命差异是多少?DbContextFactoryAddDbContext
  • \n
  • 我通常应该用于DbContextFactory项目Blazor吗?
  • \n
  • DbContext在生命周期内创建时是否有内存开销scoped
  • \n
\n

Hen*_*man 5

前提:我们希望 DbContext 的生命周期尽可能短。

对于 HTTP 服务器应用程序,我们有请求/响应周期的范围。这是理想的情况,问题已经解决:注入一个 Scoped DbContext。

对于 Blazor Server 应用程序,就像 WinForms 和 WPF 一样,我们没有如此方便的范围。所以我们必须更直接地管理DbContext。

您可以将表单(页面)的生命周期与 IDisposable 和/或 OwningComponentBase 一起使用,但该生命周期通常太长。

因此,负担转移到存储库(和/或服务):它们必须基于每个方法管理 DbContext。这就是 DbContextFactory 的用武之地:您可以简单地注入 Factory,但每个方法如下所示:

public async Task<T> GetSomething()
{
   using (var ctx = _factory.CreateContext())
   {
     ...
   }
}
Run Code Online (Sandbox Code Playgroud)

Blazor WebAssembly 应用程序不会直接使用 DbContext,因此上述内容主要适用于 Blazor Server。


MrC*_*tis 2

\n

何时使用 AddDbContextFactory 而不是 AddDbContext?

\n
\n

在 Blazor 中始终使用 DbContextFactory。但话虽如此,我相信一定有人会提出例外!

\n
\n

DbContextFactory 和 AddDbContext 之间的生命周期差异是多少?

\n
\n

DbContextFactory 管理其 DBContext 的生命周期。应用“工作单元”原则,生命周期就是工作单元的生命周期。如果将上下文直接添加到 DI 容器(例如 with )AddDbContext,那么它的生存期与 DI 容器的生命周期相同。

\n
\n

我通常应该将 DbContextFactory 用于 Blazor 项目吗?

\n
\n

上面已经回答了

\n
\n

在作用域生命周期内创建 DbContext 是否会产生内存开销?

\n
\n

当然。内存由未处置的对象使用。作用域 DbContext 的生命周期与 DI 容器的生命周期相同。在容器本身被销毁之前,不会对容器内的对象调用 Dispose。这就是为什么您从不使用 Transient DbContexts 的原因。在会话 DI 容器被销毁之前,它们不会被处置。

\n