I have a C# Core 2.0 Web API controller named 'PersonController' that handles AJAX calls from a front-end.
One of the things that this API does in its POST/PUT calls is check the validity of the person's state code (e.g., "NY") and zipcode which have been passed to the method.
Now, I have a 'lkupStates' table in my database. It includes such columns as StateCode, StateName, StateCapitol, ZipCodeLow, ZipCodeHigh, etc. Since this info never changes, it only makes sense to cache this info, although I only need some of it (StateCode, ZipCodeLow, and ZipCodeHigh).
My first question is whether to declare a static variable (e.g., '_dictStateInfo') within the 'PersonController' class, use 'services.AddMemoryCache()', or perhaps implement some other approach?
Whatever is preferable, do I initialize it in the PersonController's constructor or in Startup.cs or some other place?
I've tried using the code below in the PersonController's constructor to retrieve the info from the database:
public void ProviderController(IMemoryCache memoryCache) { _cache = memoryCache; // STATES var stateInfo = _db.lkupStateCode .Select (s => new { s.StateCode, zipInfo = new { s.ZipLOW, s.ZipHIGH } } ) .AsNoTracking() .ToDictionary(s => s.StateCode, s => s.zipInfo); //_dictStateInfo = stateInfo; //_cache.Set("dictStateInfo", stateInfo);
}
For some reason, the constructor never gets called. So I moved the database call to another section of the code, and the call worked just fine.
I then tried to go the static variable route by first defining a class:
public class ZipInfo { public decimal ZipLOW { get; set; } public decimal ZipHIGH { get; set; } }
Then declaring a private, static class-level property:
private static Dictionary<string, ZipInfo> _dictStateInfo;
And then assigning the results of the EF call:
_dictStateInfo = stateInfo ;
But it got flagged as an error -- Visual Studio effectively said that it couldn't convert from the LINQ's anonymous "zipInfo" to the _dictStateInfo's "ZipInfo" class. I suppose I could smooth things out by using the 'lkupStates' class model, but that seems like a waste of memory, since I don't need all the fields.
I would have tried going the cache route by initializing the cache also in the PersonController's constructor:
_cache.Set("dictStateInfo", stateInfo);
But since the constructor never got called, when I tried to pull it out:
if (false == _cache.TryGetValue("dictStateInfo", out Dictionary<string, ZipInfo> cacheStateInfo))
I get a "System.NullReferenceException", and indeed _cache == null
Your help would be greatly appreciated -- and despite all the foregoing, my end goal is very simple: cache (hopefully selected) data from my 'lkupStates' table.
P.S. - and yes, I understand that one big hole in the above is the constructor not being called, but I theoretically can work around that by using a static variable and migrating the code elsewhere ... that said, help getting the constructor to execute would also be greatly appreciated!