使用PooledDbContextFactory时出现Cannot access a disposed context实例错误
核心原因
你遇到的Cannot access a disposed context instance错误,本质是项目缺少Microsoft.EntityFrameworkCore.Relational包,导致EF Core的池化上下文回收逻辑无法正常执行。
详细分析
池化上下文的回收逻辑依赖Relational包
当使用AddPooledDbContextFactory时,上下文使用完毕归还到池时,会调用IResettableService.ResetState()方法重置上下文状态以便后续复用。这个重置过程需要依赖Microsoft.EntityFrameworkCore.Relational中提供的基础服务实现。如果没有安装该包,EF Core无法找到这些服务,在尝试重置已释放的上下文时就会抛出异常——这和你堆栈跟踪里显示的错误来源(DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IResettableService.ResetState())完全吻合。AddDbContext的报错是直接提示依赖缺失
改用AddDbContext时,EF Core会直接检查并注册Relational相关的核心服务,所以会立刻抛出找不到包的错误;而AddPooledDbContextFactory在初始注册时没有强制校验这个依赖,直到运行时执行上下文回收步骤才暴露出问题。安装包后解决问题的原因
安装Microsoft.EntityFrameworkCore.Relational后,EF Core能获取到重置上下文、管理关系型数据库所需的全部服务,池化上下文的回收流程可以正常完成,不会再触发已释放上下文的访问错误。
代码验证
你的仓储代码逻辑是正确的:
- 使用
await using确保上下文被正确释放 AsNoTracking()避免实体被上下文跟踪,防止后续意外访问- 所有异步操作都正确使用了
await
问题完全出在依赖包缺失,而非代码逻辑错误。
内容的提问来源于stack exchange,提问作者Androme

