EF Core DbContextFactory怎么用 EF Core DbContextFactory使用教程

来源:这里教程网 时间:2026-02-21 17:36:21 作者:

EF Core 的

IDbContextFactory<tcontext></tcontext>
是专为**按需创建独立、短生命周期 DbContext 实例**设计的接口,不是用来替代常规依赖注入方式的。它解决的核心问题是:需要在非 DI 环境(如后台线程、命令行工具、定时任务)、或需**并发/并行操作多个 DbContext**(避免线程不安全)、或需**手动控制释放时机**的场景。

什么时候该用 DbContextFactory

以下情况推荐使用工厂模式:

Task.Run
Parallel.ForEachAsync
或 Hangfire 后台任务中创建 DbContext
执行并行数据库写入(比如批量插入 100 条记录,每个用独立上下文) Blazor WebAssembly 或非 Web 环境(无内置 DI 容器)中临时访问数据库 需要明确控制 DbContext 生命周期(比如用
using
精确释放)
实现读写分离时,为读库和写库分别注册不同工厂

如何注册和获取工厂

Program.cs
(.NET 6+)中注册即可,生命周期默认为
Singleton

builder.Services.AddDbContextFactory(options =>
  options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

之后在任意服务中通过构造函数注入使用:

public class OrderService
{
  private readonly IDbContextFactory _contextFactory;

  public OrderService(IDbContextFactory contextFactory)
  {
    _contextFactory = contextFactory;
  }
}

怎么安全地创建和释放 DbContext

工厂创建的 DbContext **不由 DI 容器管理生命周期**,必须手动释放。最稳妥的方式是配合

using
语句:

public async Task CreateOrderAsync(Order order)
{
  using var context = _contextFactory.CreateDbContext();
  context.Orders.Add(order);
  await context.SaveChangesAsync();
  return true;
}

注意:
• 不要用

using var context = ...
在异步方法里跨
await
持有(会提前释放);
• 若需多次 await 操作,改用
try/finally
或确保在同一个作用域内完成所有数据库操作再释放。

和 DbContextPool 的区别别搞混

DbContextFactory ≠ DbContextPool:

DbContextFactory:每次调用
CreateDbContext()
都新建一个实例,适合“一次一用”、高并发、隔离性要求强的场景
DbContextPool
AddDbContextPool
):复用已释放的 DbContext 实例,减少 GC 压力,但仍是 Scoped 生命周期,不适合跨线程或长时间持有
两者不能混用——注册了工厂就不能再对同一上下文类型注册池化

基本上就这些。用对场景,写法简洁,关键是记得自己

Dispose

相关推荐

热文推荐