【问题标题】:Difference between AddDbContext and AddDbContextFactoryAddDbContext 和 AddDbContextFactory 之间的区别
【发布时间】:2022-01-11 18:21:46
【问题描述】:

其实我是从BlazorEF Core 开始的。在注册DbContext 时,我被卡住了。 DbContext 可以注册到AddDbContextAddDbContextFactory。但是有什么区别呢?

builder.Services.AddDbContext<DataContext>(opt => opt.UseSqlServer("..."));
builder.Services.AddDbContextFactory<DataContext>(opt => opt.UseSqlServer("..."));

从文档中我得到了以下信息:

AddDbContext:

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

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

AddDbContextFactory:

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

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

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

private readonly DataContext _dbContext;

public BlogController(IDbContextFactory<DataContext> dbFactory)
{
  // Will be created as SCOPED DbContext?
  _dbContext = dbFactory.CreateDbContext();
}

我还发现了一个类似的问题hereAddDbContextAddDbContextFactory 内的生命周期是在注册期间设置的。或者我错过了什么。

所以我的问题一般是:

  • 何时使用AddDbContextFactory 而不是AddDbContext
  • DbContextFactoryAddDbContextDbContext 的生命周期有何不同?
  • 我应该将DbContextFactory 用于Blazor 项目吗?
  • DbContext 的生命周期内创建DbContext 时是否存在内存开销?

【问题讨论】:

  • “我应该通常将 DbContextFactory 用于 Blazor 项目吗?” -> “建议为 Blazor 应用程序注册工厂...” -> 你为什么要问 我们 什么时候微软已经推荐了?
  • @CamiloTerevinto:因为对于 why 以及 howwhen 仍然存在很多混淆. Blazor 仍然很新,有两种截然不同的口味。

标签: c# entity-framework-core blazor dbcontext lifetime


【解决方案1】:

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

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

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

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

因此,负担转移到了存储库(和/或服务):他们必须在每个方法的基础上管理 DbContext。这就是 DbContextFactory 的用武之地:您可以简单地注入 Factory,但每个方法看起来像:

void DoSomething()
{
   using (var ctx = _factory.CreateContext())
   {
     ...
   }
}

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

【讨论】:

    【解决方案2】:

    何时使用 AddDbContextFactory 而不是 AddDbContext?

    在 Blazor 中始终使用 DbContextFactory。不过话虽如此,我敢肯定会有人想出一个例外!

    DbContextFactory 和 AddDbContext 与 DbContext 的生命周期有何不同?

    DbContextFactory 管理它的 DBContexts 的生命周期。应用“工作单元”原则,生命周期就是工作单元的生命周期。如果将上下文直接添加到 DI 容器中,例如使用AddDbContext,那么它会在 DI 容器的生命周期中存在。

    对于 Blazor 项目,我通常应该使用 DbContextFactory 吗?

    上面已经回答了

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

    当然。内存被未处理的对象使用。一个作用域 DbContext 在 DI 容器的整个生命周期中都存在。在容器本身被销毁之前,不会对容器内的对象调用 Dispose。这就是为什么您从不使用 Transient DbContexts 的原因。在会话 DI 容器被销毁之前,它们不会被释放。

    【讨论】:

      猜你喜欢
      • 2021-03-09
      • 1970-01-01
      • 2021-12-25
      • 2020-05-10
      • 2014-09-20
      • 2010-10-28
      • 2015-10-04
      • 2012-08-12
      • 2011-02-18
      相关资源
      最近更新 更多