为什么 DBContext 放入 IMemoryCache 后会被释放(.NET Core / EF Core)

2023-12-05

我试图将 db-data 的子集放入 IMemoryCache 中,但第二次调用该应用程序时,出现错误:

ObjectDisposeException:无法访问已处置的对象。导致此错误的一个常见原因是处置从依赖项注入解析的上下文,然后尝试在应用程序的其他位置使用相同的上下文实例。如果您在上下文上调用 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 在我第一次将其放入缓存后就被释放了。我该如何处理这个问题?


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

但那个WebDbContext对象仅在当前 HTTP 请求的生命周期内可用。一旦 HTTP 请求完成,ASP.NET Core 就会将其删除。这就是为什么你会看到它被处置。

Update:我明白你在做什么。问题就在这里:

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

那不缓存数据。缓存查询(IQueryable)。在枚举该查询(循环遍历它)之前,该查询不会被执行。这称为“延迟加载”。所以你的GetArticles实际上每次调用时都会再次执行查询。

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

您需要强制它立即执行查询。一个简单的方法是调用ToList():

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

您需要将属性类型更改为IEnumerable too.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 DBContext 放入 IMemoryCache 后会被释放(.NET Core / EF Core) 的相关文章

随机推荐