aspnet/Caching

Using SizeLimit with MemoryCache cause EF Core queries to fail

ajcvickers opened this issue · 4 comments

Moved from dotnet/efcore#12157 filed by @sanishmistry

Steps to reproduce

Use MemoryCache with ASP.NET Core in Startup.cs

        services.AddMemoryCache(o => {
            o.SizeLimit = 5000;
            
        });

Then do a query

    public IActionResult Test([FromServices] AppDbContext db)
    {
        var x = db.PostCodes.Where(p => p.Value == "XXXX").ToList();
...
    }

The issue

You get an exception like this

                An unhandled exception has occurred while executing the request
        System.InvalidOperationException: Cache entry must specify a value for Size when SizeLimit is set.
            at Microsoft.Extensions.Caching.Memory.MemoryCache.SetEntry(CacheEntry entry)
            at Microsoft.Extensions.Caching.Memory.CacheEntry.Dispose()
            at Microsoft.Extensions.Caching.Memory.CacheExtensions.Set[TItem](IMemoryCache cache, Object 
        key, TItem value)
            at 
        Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc] 
        (Object cacheKey, Func`1 compiler)
            at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
            at Remotion.Linq.QueryableBase`1.GetEnumerator()
            at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
            at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

Further technical details

EF Core Version : 2.0.2
MySQL version: 5.7.22-0ubuntu0.16.04.1 - (Ubuntu)
Operating system: Ubuntu 16.04.4 LTS
Pomelo.EntityFrameworkCore.MySql version: 2.0.1

Comment from @smitpatel

This should probably moved to aspnet/Caching repo. We use Set method directly which has no way to specify size for the entry. MemoryCache extension methods create CacheEntry itself so it should set value for size. (especially when they have check for it)

@ajcvickers MemoryCache doesn't have a mechanism to measure the size of objects being added to the cache, that's why it punts that to the callers. EF might not be much better of here, do you know how big the entity is?

Discussed offline with @divega and came up with some ways for EF to deal with this. He'll open an new issue. Closing this one.