Почему DBContext удаляется после помещения его в IMemoryCache (.NET Core / EF Core) - PullRequest
0 голосов
/ 29 октября 2018

Я пытаюсь поместить подмножество db-данных в IMemoryCache, но при втором вызове приложения я получаю сообщение об ошибке:

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

Фрагмент моего кода:

    public class ArticleRepository : IArticleRepository
    {
        private readonly WebDbContext _WebDbContext;
        private readonly IMemoryCache _cache;

        public ArticleRepository(WebDbContext WebDbContext, IMemoryCache cache)
        {
            _WebDbContext = WebDbContext;
            _cache = cache;
        }

        public IQueryable<Articles> WebshopArticles
        {
            get
            {
                return _cache.GetOrCreate("WebshopArticles", entry =>
                {
                    entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
                    return _WebDbContext.Article.Include(s => s.Details);
                });                
            }
        } 

        public IQueryable<Articles> GetArticles(string category)
        {
            return WebshopArticles.FirstOrDefault(s => s.Category == Category);
        }
    }

Похоже, что DBContext удаляется после того, как я впервые поместил его в кеш. Как я могу справиться с этим?

1 Ответ

0 голосов
/ 29 октября 2018

Вы используете внедрение зависимостей, чтобы получить экземпляр вашего WebDbContext через конструктор. ASP.NET Core делает это, инициируя для вас объект WebDbContext и вставляя его в вызов конструктора, когда он создает экземпляр вашего класса репозитория.

Но этот WebDbContext объект доступен только на время существования текущего HTTP-запроса. После завершения HTTP-запроса ASP.NET Core избавляется от него. Вот почему вы видите, что он расположен.

Обновление: Я вижу, что вы делаете. Проблема здесь:

return _WebDbContext.Article.Include(s => s.Details);

Это не кеширует данные. Это кэширует запрос (IQueryable). Запрос не будет выполнен, пока вы не перечислите это (цикл через него). Это упоминается как "ленивая загрузка". Таким образом, ваш GetArticles фактически выполняет запрос каждый раз, когда он вызывается.

При первом использовании (в том же HTTP-запросе, который вы его кэшировали), это работает Но когда вы используете его во второй раз, контекст удаляется, и запрос не может быть выполнен.

Вам нужно заставить его выполнить запрос сразу же. Самый простой способ - позвонить ToList():

return _WebDbContext.Article.Include(s => s.Details).ToList();

Вам также потребуется изменить тип свойства на IEnumerable.

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