Search code examples
entity-frameworklinq-to-sql.net-corememorycache

Memory Cache .Net Core Not Persisting Values


I have a .NET Core 2.1 application. In Startup.cs configuration method, I use:

services.AddDbContext<ApplicationDbContext>(options =
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
...

services.AddMemoryCache();   

Then in my controller:

public class DropDownListController : Controller
{
    private readonly ApplicationDbContext _context;
    private readonly IMemoryCache _memoryCache;

    private const string ProvidersCacheKey = "providers";
    private const string AgenciesCacheKey = "agencies";

    public DropDownListController(ApplicationDbContext context, IMemoryCache memoryCache )
    {
        _context = context;
        _memoryCache = memoryCache;
    }
}

and in the controller also, the method to get the dropdownlist:

public JsonResult GetProvider()
{
    IEnumerable<DropDownListCode.NameValueStr> providerlist;

    if (_memoryCache.TryGetValue(ProvidersCacheKey, out providerlist))
    {
        return Json(providerlist);
    }
    else
    {
        MemoryCacheEntryOptions cacheExpirationOptions = new MemoryCacheEntryOptions();
        cacheExpirationOptions.AbsoluteExpiration = DateTime.Now.AddDays(30);
        cacheExpirationOptions.Priority = CacheItemPriority.Normal;

        DropDownListCode um = new DropDownListCode(_context);
        var result = um.GetProviderList();

        _memoryCache.Set(ProvidersCacheKey, result);

        return Json(result);
    }
}

When I set a breakpoint on the line:

return Json(providerlist);

I see the ProvidersCacheKey is in the _memoryCache, but it has no value.

What happened to the data?

When I do a Quick Watch on _memoryCache, I can see the DbContext object was destroyed. But how can that be, the code works fine but the cache object does not have the data I saved to it.

Any help would be appreciated.


Solution

  • The method to get providers is:

    public IEnumerable<NameValueStr> GetProviderList()
        {
            var providerlist = (from a in _context.AgencyProvider
                                where a.Provider == a.AgencyId
                                select new NameValueStr
                                {
                                    id = a.Provider,
                                    name = a.Name
                                });
    
            return providerlist.Distinct();
        }
    

    Adding "ToList()" in the calling method worked:

    MemoryCacheEntryOptions cacheExpirationOptions = new MemoryCacheEntryOptions();
                cacheExpirationOptions.AbsoluteExpiration = DateTime.Now.AddMinutes(30);
                cacheExpirationOptions.Priority = CacheItemPriority.Normal;
                DropDownListCode um = new DropDownListCode(_context);
                var result = um.GetProviderList().ToList();
                _memoryCache.Set(ProvidersCacheKey, result);
                return Json(result);
    

    All credit goes to Steve Py… Thank you sir!