使用EF Core内存数据库时触发ObjectDisposedException异常求排查
问题分析与解决方案
核心问题:async void 导致DbContext被提前释放
服务层的Create方法使用async void是引发异常的根本原因:
- ASP.NET Core中,
DbContext默认是Scoped生命周期,请求结束后会被框架自动释放。 - 控制器同步调用
showtimeService.Create(weirdModel)后直接返回201,请求上下文提前结束,WeirdContext被释放。但Create方法内的await imdbService.fetchSomestuff(...)异步操作还未完成,后续执行仓储的Add和SaveChanges时,Context已经处于Disposed状态,因此抛出System.ObjectDisposedException。
修复步骤:
- 服务层方法改为
async Task:
public async Task Create(WeirdModel weirdModel) { var extraDataModel = await imdbService.fetchSomestuff(weirdModel.Id); weirdModel.extraData = mapper.Map<extraData>(extraDataModel); var weirdEntity = mapper.Map<WeirdEntity>(weirdModel); WeirdRepository.Add(weirdEntity); // 修正变量名拼写错误:原代码用了未定义的showtimeEntity }
- 控制器改为异步调用,等待服务方法执行完成:
[HttpPost] public async Task<IActionResult> Post([FromBody] WeirdModel weirdModel) { await showtimeService.Create(weirdModel); return StatusCode(201); }
次要问题:SaveChanges返回值误用
仓储Add方法中,var id = _context.SaveChanges()是错误用法:
SaveChanges()返回的是受影响的行数,并非新添加实体的主键ID。- 正确做法是:调用
SaveChanges()后,EF Core会自动填充实体的主键属性,直接使用实体的Id即可:
public WeirdEntity Add(WeirdEntity weirdEntity) { _context.Showtimes.Add(weirdEntity); // 修正变量名:原代码用了未定义的showtimeEntity,且应使用私有字段_context而非context _context.SaveChanges(); return GetCollection(ent => ent.Id == weirdEntity.Id).FirstOrDefault(); }
额外注意:代码拼写错误
原代码存在几处变量名不一致问题,需一并修正:
- 仓储构造函数接收的是
WeirdContext,但方法内误用了context而非私有字段_context - 服务层中映射得到
weirdEntity,但调用仓储时传了未定义的showtimeEntity
内容的提问来源于stack exchange,提问作者Daniel Vega
相关产品推荐
相关产品推荐

