I want to store null for some of the keys in HttpRuntime.Cache
as I dont want to again go to Database to find that there is no entry for that key.
So first time, it goes to database and fills the cache. The intent is to serve the following calls using cached data instead of doing the database call.
Here is the code that I am using the following:
Info info = null;
if (HttpRuntime.Cache["Info_" + id.ToString() + "_" + quantity.ToString()] != null)
info = HttpRuntime.Cache["Info_" + id.ToString() + "_" + quantity.ToString()] as Info;
if (info == null)
{
info = (from dd in dc.Infos
where dd.id == id && dd.active == true && dd.quantitytooffset == quantity
select dd).SingleOrDefault();
HttpRuntime.Cache.Add("Info_" + id.ToString() + "_" + quantity.ToString(), info, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, null);
}
The last line of code i.e. HttpRuntime.Cache.Add throws an System.ArgumentNullException: Value cannot be null.
Any idea if this is possible or I need to use other datastructure to store null values and look up later?
Although the internals of HttpRuntime.Cache do protect the set/get of values within the internal cache structures, it does not help the consumer of the Cache. There are reasonable, highly publicized patterns for setting and getting values. Here is a simple example with comments.
If the value is null, the Add method places an item in the cache with a key of Key1, a value of Value 1, an absolute expiration of 60 seconds, and a high cache priority. It also uses the onRemove method as an argument. This allows the RemovedCallback method to be called when this item is removed from the cache.
The cache key used to reference the item. The item to be added to the cache. The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null. The time at which the added object expires and is removed from the cache.
If the item is not requested from the cache before the date in the absoluteExpirationparameter, the item is removed from the cache. The item added to the cache using this overload of the insert method is inserted with a priority of Default. See also DateTime
You could use your own "null" value to place into cache. For example,
private static Info NULL_INFO = new Info();
Then you could use that instead of null in HttpRuntime.Cache.Add and later after retrieval from cache check that you didn't get your NULL_INFO
if ( info == NULL_INFO) // if you don't have equality operator overloaded, otherwise you'd better use ReferenceEquals()
// return empty data
else if (info == null)
// proceed with try to load from database
I wrote a blog post recently about how the null
keyword is often abused leading to this kind of confusion. In your particular case I would look at using an option type to indicate the lack or presence of data rather than null.
I have a simple implementation of an Option type you can use here
The usage would then be something like:
if (HttpRuntime.Cache["xyz"] == null)
// Impossible to make a distinction between whether or not the cache value is missing
// or if it is present but explicitly a null value...
HttpRuntime.Cache["xyz"] = Option<String>.None();
// We have now explicitly stated that the cache contains xyz but the value is null...
HttpRuntime.Cache["xyz"] = Option<String>.Some("hello world");
if (HttpRuntime.Cache["xyz"].IsSome)
{
// cache contains a non-null value for xyz...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With