将DBContext放入IMemoryCache(.NET Core/EF Core)之后为什么要处理它

Cri*_*bAd 3 c# entity-framework .net-core asp.net-core

我正在尝试将一个db-data的子集放在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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在第一次将它放入缓存后,看起来像DBContext.我怎么处理这个?

Gab*_*uci 10

您正在使用依赖注入WebDbContext通过构造函数获取您的实例.ASP.NET Core通过WebDbContext为您启动一个对象并在创建存储库类的实例时将其注入构造函数调用来实现此目的.

但该WebDbContext对象仅在当前HTTP请求的生命周期内可用.一旦HTTP请求完成,ASP.NET Core就可以摆脱它.这就是你看到它处理掉的原因.

更新:我明白你在做什么.问题出在这里:

return _WebDbContext.Article.Include(s => s.Details);
Run Code Online (Sandbox Code Playgroud)

这不会缓存数据.这会缓存query(IQueryable).在您枚举(遍历它)之前,查询不会执行.这被称为"延迟加载".因此GetArticles,每次调用时,您实际上都会再次执行查询.

第一次使用它时(在缓存它的同一HTTP请求中),它可以工作.但是当您第二次使用它时,将处理上下文并且无法执行查询.

您需要强制它立即执行查询.一个简单的方法是打电话ToList():

return _WebDbContext.Article.Include(s => s.Details).ToList();
Run Code Online (Sandbox Code Playgroud)

您还需要更改属性类型IEnumerable.