AddDbContext和AddDbContextFactory之间的差异



实际上我是从BlazorEF Core开始的。在注册DbContext时,我被卡住了。DbContext可以向AddDbContext或向AddDbContextFactory注册。但是有什么区别呢?

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

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

AddDbContext:

使用依赖项注入时使用此方法。。。

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

AddDbContextFactory:

对于Blazor应用程序和其他依赖项注入范围与上下文生存期不一致的情况,建议注册工厂。。。

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

那么,我们是否可以全局地说,如果程序需要从不同线程访问DbContext,或者同时有必要向AddDbContextFactory注册上下文,因为当它被创建时(例如在控制器中(,提升时间被设置为scoped,因此我们每次都获得一个新的DbContext

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

我在这里也发现了一个类似的问题。并且在注册期间设置AddDbContextAddDbContextFactory内的寿命。或者我错过了什么。

所以我的问题一般是:

  • 何时使用AddDbContextFactory而不是AddDbContext
  • DbContextFactoryAddDbContextDbContext的寿命差异是什么
  • 对于Blazor项目,我通常应该使用DbContextFactory
  • 当在scoped生存期内创建DbContext时,是否存在内存开销

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

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

对于Blazor Server应用程序,就像WinForms和WPF一样,我们没有这么方便的Scopes。因此,我们必须更直接地管理DbContext。

您可以使用IDisposable和/或OwningComponentBase的窗体(页(的生存期,但该生存期通常太长。

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

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

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

何时使用AddDbContextFactory而不是AddDbContext?

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

DbContextFactory和AddDbContext与DbContext的生存期差异是什么?

DbContextFactory管理其DBContexts的生命周期。应用";工作单位;原则和生命周期是工作单元的生命周期。如果您将上下文直接添加到DI容器中,例如使用AddDbContext,那么它将在DI容器的生命周期内存在。

我通常应该为Blazor项目使用DbContextFactory吗?

已在上回答

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

当然。内存由未变形的对象使用。作用域DbContext在DI容器的生存期内有效。在容器本身被销毁之前,不会对容器内的对象调用Dispose。这就是为什么您从不使用Transient DbContexts。在会话DI容器被销毁之前,它们不会被处理。

相关内容

  • 没有找到相关文章

最新更新