EF Core 8报错:无法访问已释放的DbContext实例求排查
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'BKRContext'.
相关代码
项目启动配置(Program.cs)
using BKR.DB; using BKR.Web.Components; using BKR.WEB.Services; using BKR.WEB.Services.Contracts; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddDbContextPool<BKRContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("BKRConnection"), sqlServerOptionsAction: sqlOptions => { sqlOptions.EnableRetryOnFailure(); }); }); builder.Services.AddScoped<ICustomerService, CustomerService>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAntiforgery(); app.MapRazorComponents<App>().DisableAntiforgery().AddInteractiveServerRenderMode(); app.Run();
CustomerService实现代码
using BKR.Model; using BKR.WEB.Services.Contracts; using System.Net.Http.Json; using System.Text.Json; using Microsoft.AspNetCore.WebUtilities; using BKR.DB; using Microsoft.EntityFrameworkCore; namespace BKR.WEB.Services { public class CustomerService : ICustomerService { private readonly BKRContext dbcontext; public CustomerService(BKRContext bkrdbcontext) { this.dbcontext = bkrdbcontext; } public async ValueTask<BKR.Model.Customer> CreateCustomer(BKR.Model.Customer dto) { BKR.Model.Customer bolObj = new BKR.Model.Customer() try { var result = await this.dbcontext.Customers.AddAsync(bolObj); await this.dbcontext.SaveChangesAsync();// <<-- Error here return result.Entity; } catch (Exception ex) { throw; } } } }
BKRContext实现代码
using BKR.Model; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace BKR.DB; public class BKRContext : DbContext { //public BKRContext() //{ //} public BKRContext(DbContextOptions<BKRContext> dbContextOptions) : base(dbContextOptions) { //Database.EnsureCreated(); } //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) //{ // IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build(); // optionsBuilder.UseSqlServer(configuration.GetConnectionString("BKRConnection")); //} }
问题
请问该错误的产生原因是什么?
错误原因分析
Blazor Server的Scoped生命周期特性冲突:Blazor Server中Scoped服务的生命周期与**用户电路(Circuit)**绑定,而非传统ASP.NET Core的请求生命周期。
AddDbContextPool默认将DbContext注册为Scoped,当用户关闭浏览器、电路超时或断开时,对应的Scoped DbContext会被DI容器释放。若此时仍持有该DbContext引用并尝试调用方法(如SaveChangesAsync),就会触发已释放错误。异步操作的上下文延续问题:
CreateCustomer是异步方法,若执行过程中因等待数据库响应被挂起,恢复执行时可能已超出原Scoped上下文的生命周期,此时DbContext已被DI容器回收,后续调用自然报错。服务注册与场景不匹配:
CustomerService被注册为Scoped,它所持有的DbContext会跟随电路生命周期。一旦电路结束,DbContext被释放,若后续有延迟执行的代码访问该DbContext,就会触发错误。
内容的提问来源于stack exchange,提问作者Jan Gravgaard

