I'm trying to put a subset of db-data in an IMemoryCache, but the 2nd time I call the application, I get an error:
ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'WebDbContext'.
My Code snippet:
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);
}
}
It looks like DBContext is disposed after the first time I put it in cache. How can i handle this?
You're using dependency injection to get an instance of your WebDbContext
through your constructor. ASP.NET Core does this by initiating a WebDbContext
object for you and injecting it into the constructor call when it creates an instance of your repository class.
But that WebDbContext
object is only available for the life of the current HTTP request. Once that HTTP request is complete, ASP.NET Core gets rid of it. That's why you see it disposed.
Update: I see what you're doing. The problem is here:
return _WebDbContext.Article.Include(s => s.Details);
That does not cache the data. That caches the query (IQueryable
). The query doesn't get executed until you enumerate that (loop through it). This is refered to as "lazy loading". So your GetArticles
actually performs the query again each time it's called.
The first time you use it (in the same HTTP request you cached it), it works. But when you use it the second time, the context is disposed and the query can't be executed.
You need to force it to execute the query right away. An easy way is to call ToList()
:
return _WebDbContext.Article.Include(s => s.Details).ToList();
You'll need to change the property type to IEnumerable
too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With