2

I have this code on my Startup.

var connection = Configuration.GetConnectionString("DefaultConnection")?.Replace("[BD_PASS]", Environment.GetEnvironmentVariable("BD_PASS"));
services.AddDbContext<BdContext>(options => options.UseSqlServer(connection));

services.AddMemoryCache(op =>
            {
                op.SizeLimit = int.Parse(Environment.GetEnvironmentVariable("CACHE_SIZE_LIMIT") ?? "10");
            });

The problem is that I wasn't aware that Entity Framework Core would intercept my queries against the database. So, I am getting a

 _context.Product.ToList();

But I am getting this message when the code above is run.

cache entry must specify a value for size when the size limit is set

Is there anything I could do at the configuration level to say "Hey EFC, don't you bother to cache anything."

5
  • Is this relevant for you? stackoverflow.com/questions/58406143/… Commented May 18, 2020 at 23:32
  • Thanks, for the comment @NateBarbettini, but it doesn't. All I could find on the internet were people who didn't desire to use the size limit, but some library was using. Here, I really want to use Size_Limit, since this is a requirement of my code. Commented May 18, 2020 at 23:33
  • Can you post a short but complete repro of the issue? Commented May 19, 2020 at 0:10
  • I guess there's nothing more to add, besides that I am using ASP.NET Core 2.2 and that The request is made against a transient DbContext created for each request. Commented May 19, 2020 at 1:13
  • 1
    Ah, I understand your question now. You want to use MemoryCache with certain parameters, but under the hood EF Core is also using MemoryCache and isn't playing nice. Commented May 19, 2020 at 15:02

1 Answer 1

5

Entity Framework Core uses what's called the "shared cache". It depends on IMemoryCache registered in the service container. The solution isn't to stop EF Core from using a cache, it's to use a different cache for your services that understand cache size limits.

In other words, create a tailored cache for your own use:

public class LimitedMemoryCache 
{
    public MemoryCache Cache { get; private set; }

    public LimitedMemoryCache(int limit)
    {
        Cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 10
        });
    }
}

And register it as a separate singleton:

var cacheLimit = int.Parse(Environment.GetEnvironmentVariable("CACHE_SIZE_LIMIT") ?? "10");
services.AddSingleton(new LimitedMemoryCache(cacheLimit));

Classes can choose to use this cache by injecting LimitedMemoryCache instead of IMemoryCache. Entity Framework Core and anything else that depends on IMemoryCache directly can now coexist without any problems.

This is mentioned on the in-memory cache docs, which is how I learned about it myself:

... When a size limit is set on a cache, all entries must specify a size when being added. This can lead to issues since developers may not have full control on what uses the shared cache. For example, Entity Framework Core uses the shared cache and does not specify a size. If an app sets a cache size limit and uses EF Core, the app throws an InvalidOperationException. When using SetSize, Size, or SizeLimit to limit cache, create a cache singleton for caching.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.