已经看到很多类似的问题,但是没有一个适合我的情况或解决了我的问题。
System.ObjectDisposedException:无法访问已处置的对象。一种 导致此错误的常见原因是处理已解决的上下文 从依赖注入,然后稍后尝试使用相同的 应用程序中其他位置的上下文实例。如果您可能会发生这种情况 在上下文上调用Dispose()或将上下文包装在 使用语句。如果使用依赖注入,则应让 依赖项注入容器负责处理上下文 实例。
控制器:
[HttpGet]
public IActionResult GetAllTags()
{
try
{
return Ok(GetAll());
}
catch(Exception ex)
{
return ControllerHelper.LogAndReturnBadRequest(_logger, ex);
}
}
private IEnumerable<TagDto> GetAll()
{
IEnumerable<TagDto> tags;
if (!_cache.TryGetValue(CacheKeys.States, out tags))
{
tags = _service.GetAll()?.Select(t => _mapper.Map<TagDto>(t));
if(tags != null)
_cache.Set(CacheKeys.States, tags);
}
return tags;
}
Startup.cs
services.AddMemoryCache();
我正在逐行调试代码,但是即使在代码的最后一行之后,也没有任何错误。
我看到的错误是在Kestrel控制台中。 需要注意的是,该错误仅在从_cache读取标签时发生,而在直接从数据库直接获取标签时不会发生。
许多类似的问题都涉及到处理对象,但是在这里您可以看到我的代码中没有dispose()或using()。
请帮助
答案 0 :(得分:1)
我的猜测是,在存储在缓存中之前,您需要对查询结果进行混合处理。 Linq使用延迟执行,这意味着在您尝试枚举结果之前,实际上不会查询基础源。因此,您只是在缓存中存储一个 query ,并且当您尝试检索实际数据时,基础上下文已被处置。
向查询中添加ToList
并将列表存储在缓存中:
tags = _service.GetAll()?.Select(t => _mapper.Map<TagDto>(t)).ToList();
我还要注意,返回序列的linq查询的结果从不为空。它可能是 empty ,因此,如果您不想缓存空结果,可以将null检查更改为if (tags.Any())
。