我在用着EF Core和...一起Postgres(可能并不重要)在一个.NET Core 3.1 控制台应用程序.
该程序使用一个共享项目(以及解决方案的其他组件),所有业务逻辑均使用简单的 CQRS 类型模式和 Mediator 来实现。
在一处,我从数据库中检索大小为 10 - 100MB 的大型对象。这种情况并不常见,因此本身不是问题。在现代硬件上只需几分之一秒的时间。
问题是,由于某种原因,这些对象在命令执行之间被缓存在数据上下文中,就像数据上下文没有被释放一样。
我不明白为什么,因为我将 DI 容器(内置标准)内的 DbContext 注册为瞬态。我的理解是,它应该在每次请求时创建一个新实例,而垃圾收集器应该处理其余的事情。
注册码是这样的:
static IServiceProvider ConfigureServiceProvider()
{
IServiceCollection services = new ServiceCollection();
DbContextOptions<MyAppDbContext> dbContextOptions = new DbContextOptionsBuilder<MyAppDbContext>()
.UseNpgsql(Configuration.GetConnectionString("MyApp.Db"))
.Options;
services.AddSingleton(dbContextOptions);
services.AddDbContext<MyAppDbContext>(options => options.UseNpgsql(Configuration.GetConnectionString("MyApp.Db"), options => options.EnableRetryOnFailure()), ServiceLifetime.Transient);
services.AddTransient<IMyAppDbContext>(s => s.GetService<MyAppDbContext>());
// (...)
}
然后命令以这种方式使用它:
public class RecalculateSomething : IRequest
{
public Guid SomeId { get; set; }
public class Handler : IRequestHandler<RecalculateSomething>
{
private IMyAppDbContext context;
private readonly IMediator mediator;
public Handler(IMyAppDbContext context, IMediator mediator)
{
this.context = context ?? throw new ArgumentNullException(nameof(context));
this.mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
public async Task<Unit> Handle(RecalculateSomething request, CancellationToken ct)
{
// (...)
}
}
}
有谁知道问题是什么?我在配置 DI 容器时做错了什么吗?或者其他东西,比如我在某处保存的参考资料(找不到)。解决此类问题的最佳方法是什么?
顺便说一句,我通过强制它每次从 DbContextOptions 创建一个新的 DbContext 来“修复它”,但这更多的是一种解决方法。想知道核心问题是什么。