You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写C# .NET Core单元测试时遇“无法访问已释放上下文实例”错误求助

解决System.ObjectDisposedException: 无法访问已释放的DbContext实例问题

错误信息

System.ObjectDisposedException : 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: 'DbContext'.

问题场景

在C# .NET Core项目中编写单元测试,DbContext配置为作用域服务,数据访问层(DAL)为瞬态服务,仅单个测试方法触发该错误,其他方法运行正常。

问题根源及修复方案

1. 单元测试中ServiceProvider的Mock配置错误

Setup方法里配置GetService时,错误地使用了实例的typeof,而非DbContext类型本身:

原错误代码:

var dbContext = GetDatabaseContext();
_mockServiceProvider.Setup(x => x.GetService(typeof(dbContext))) 
    .Returns(dbContext);

修复后代码:
用DbContext的类型而非实例来设置mock:

var dbContext = GetDatabaseContext();
_mockServiceProvider.Setup(x => x.GetService(typeof(DbContext)))
    .Returns(dbContext);
// 或者更类型安全的写法
_mockServiceProvider.Setup(x => x.GetService<DbContext>())
    .Returns(dbContext);

2. DbContext实体主键配置错误

OnModelCreating方法中重复设置实体主键,会导致EF Core模型异常,影响上下文生命周期管理:

原错误代码:

entity.HasKey(e => new { e.AnimalId });
entity.HasKey(e => new {e.AnimalName});

修复后代码:
将AnimalId和AnimalName合并为复合主键:

entity.HasKey(e => new { e.AnimalId, e.AnimalName });

3. 单元测试中的笔误

测试方法调用UpdateRecord时,误用了未初始化的_animalDataAccess,应改为类中初始化的_animalRetentionDataAccess:

原错误代码:

var result = await _animalDataAccess.UpdateRecord(50, true, animal);

修复后代码:

var result = await _animalRetentionDataAccess.UpdateRecord(50, true, animal);

4. 可选优化:避免返回实体因上下文释放报错

若需要在方法外部访问返回的实体,可在返回前将实体从DbContext跟踪中分离:

if (updateRecord != null)
{
    updateRecord.AnimalRetention = (int)animalRetention;
    updateRecord.IsAnimalRetention = isAnimalRetention;
    await dbContext.SaveChangesAsync();
    dbContext.Entry(updateRecord).State = EntityState.Detached; // 分离实体,避免后续访问报错
    return updateRecord;
}

验证修复

完成上述修改后重新运行单元测试,System.ObjectDisposedException错误应不再出现,UpdateRecord方法可正常完成数据更新操作。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:20:23