EntityFrameworkCore.Cacheable
EntityFrameworkCore.Cacheable copied to clipboard
Cache Not "Flushing" and Going Back to Database
Describe what is not working as expected.
The cache doesn't seem to be "flushing" and going back to the database when a record is added after the query is cached. An example test method is below to demonstrate.
Steps to reproduce
/// <summary>
/// Ensure that the cache is flushing correctly when new records are added.
/// </summary>
[TestMethod]
public void CacheFlushingTest()
{
MemoryCacheProvider.ClearCache();
var loggerProvider = new DebugLoggerProvider();
var loggerFactory = new LoggerFactory(new[] { loggerProvider });
var options = new DbContextOptionsBuilder<BloggingContext>()
.UseLoggerFactory(loggerFactory)
.UseInMemoryDatabase(databaseName: "EntityExpressionTest")
.Options;
// create test entries
using (var initContext = new BloggingContext(options))
{
initContext.Blogs.Add(new Blog { BlogId = 1, Url = "http://sample.com/cats" });
initContext.Blogs.Add(new Blog { BlogId = 2, Url = "http://sample.com/catfish" });
initContext.SaveChanges();
}
using (var entityContext = new BloggingContext(options))
{
// shoud not hit cache, because first execution
var result = entityContext.Blogs
.Where(d => d.BlogId > 1)
.Cacheable(TimeSpan.FromMinutes(5))
.ToList();
// shoud hit cache, because second execution
var cachedResult = entityContext.Blogs
.Where(d => d.BlogId > 1)
.Cacheable(TimeSpan.FromMinutes(5))
.ToList();
Assert.AreEqual(result.Count, cachedResult.Count);
}
// create additional test entries
using (var initContext = new BloggingContext(options))
{
initContext.Blogs.Add(new Blog { BlogId = 3, Url = "http://sample.com/dogs" });
initContext.SaveChanges();
}
using (var entityContext = new BloggingContext(options))
{
// shoud not hit cache
var result = entityContext.Blogs
.Where(d => d.BlogId > 1)
.Cacheable(TimeSpan.FromMinutes(5))
.ToList();
// shoud hit cache, because second execution
var cachedResult = entityContext.Blogs
.Where(d => d.BlogId > 1)
.Cacheable(TimeSpan.FromMinutes(5))
.ToList();
Assert.AreEqual(2, cachedResult.Count);
}
// find "cache hit" log entries
var logs = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit);
// cache should hit one time
Assert.IsTrue(logs.Count() == 1);
}
Further technical details
EntityFrameworkCore.Cacheable version: 2.0.0 EF Core version: 2.2.3 IDE: Visual Studio 2019.0
@SteffenMangold any point to talk about it? I can analyze more deeply and understand what has been described here.