Невозможно получить доступ к удаленному объекту с помощью MemoryCache - PullRequest
0 голосов
/ 02 мая 2019

Я получаю это сообщение:

System.ObjectDisposedException: Невозможно получить доступ к удаленному объекту.Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения.Это может произойти, если вы вызываете Dispose () для контекста или заключаете контекст в оператор using.Если вы используете внедрение зависимостей, вы должны позволить контейнеру внедрения зависимостей избавиться от экземпляров контекста.

Контроллер:

    [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 () или использование () в моем коде.

1 Ответ

1 голос
/ 02 мая 2019

Полагаю, вам нужно гидрировать результаты вашего запроса перед сохранением в кеше.Linq использует отложенное выполнение , что означает, что базовый источник не будет запрашиваться до тех пор, пока вы не попытаетесь перечислить результаты.Таким образом, вы просто сохраняете запрос в кэше, и к тому времени, когда вы пытаетесь получить фактические данные, базовый контекст удаляется.

Добавьте ToList к вашему запросу и сохраните список в кеше:

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

Я бы также отметил, что результатом запроса linq, который возвращает последовательность, будет никогда не будет нулевым.Это может быть пусто , поэтому, если вы не хотите кэшировать пустой результат, вы можете изменить нулевую проверку на if (tags.Any()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...