无法使用MemoryCache访问已处置的对象

时间:2019-05-02 00:49:12

标签: c# asp.net-core entity-framework-core

已经看到很多类似的问题,但是没有一个适合我的情况或解决了我的问题。

  

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读取标签时发生,而在直接从数据库直接获取标签时不会发生。 enter image description here

这是我从邮递员的要求中得到的: enter image description here

许多类似的问题都涉及到处理对象,但是在这里您可以看到我的代码中没有dispose()或using()。

请帮助

1 个答案:

答案 0 :(得分:1)

我的猜测是,在存储在缓存中之前,您需要对查询结果进行混合处理。 Linq使用延迟执行,这意味着在您尝试枚举结果之前,实际上不会查询基础源。因此,您只是在缓存中存储一​​个 query ,并且当您尝试检索实际数据时,基础上下文已被处置。

向查询中添加ToList并将列表存储在缓存中:

tags = _service.GetAll()?.Select(t => _mapper.Map<TagDto>(t)).ToList();

我还要注意,返回序列的linq查询的结果从不为空。它可能是 empty ,因此,如果您不想缓存空结果,可以将null检查更改为if (tags.Any())