在HttpRuntime.Cache.Add中为空,值为null

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在HttpRuntime.Cache.Add中为空,值为null相关的知识,希望对你有一定的参考价值。

我想在HttpRuntime.Cache中为某些键存储空值,因为我不想再次进入数据库以查找该键没有条目。

因此,它第一次进入数据库并填充缓存。目的是使用缓存的数据而不是执行数据库调用来服务以下调用。

这是我使用以下代码:

            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);
        }

代码的最后一行,即HttpRuntime.Cache.Add抛出System.ArgumentNullException:值不能为null。

是否有可能,或者我需要使用其他数据结构来存储空值并稍后查找?

答案

您可以使用自己的“ null”值放入缓存。例如,

private static Info NULL_INFO = new Info();

然后,您可以在HttpRuntime.Cache.Add中使用它而不是null,并且稍后从缓存中检索后,检查是否没有得到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
另一答案

我最近写了一篇blog post,内容涉及null关键字经常被滥用而导致这种混乱的情况。在您的特定情况下,我将考虑使用[option type指示是否存在数据而不是数据。

我有一个可以使用here的Option类型的简单实现

用法将类似于:

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...
}
另一答案

您只需要检查从数据源获取的值是否不为null,然后再尝试将其添加回缓存,请参见下文:

        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();
        if (info != null)
        {
            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);
        }
    }

由于您在代码开头使用as Info转换,因此如果密钥不存在于缓存中,它将始终返回null值,因此您无需存储[C0 ]值在缓存中。在缓存中存储null值实际上没有任何用处,因此,该框架不允许您这样做是有原因的。

另外,请稍作说明,一次创建缓存密钥,然后重新使用它,而不是每次使用时都要重新构造它。例如:

null

然后使用:

var key = string.Format("Info_{0}_{1}", id, quantity);

访问它时,它使您的代码更不会出现拼写错误。

另一答案

这是解决此常见问题的通用静态类/方法(null表示“我已检查并且它不存在,不需要再次检查”。)。]]

此解决方案像其他答案一样包装值。

用法示例

HttpRuntime.Cache[key]

实施

    var user = await Cached.Get(
          _cache, userName, 
          async () => _dbContext.LoadAsync<DbUser>(userName)));

以上是关于在HttpRuntime.Cache.Add中为空,值为null的主要内容,如果未能解决你的问题,请参考以下文章

突然发现缓存这么好用

如何设置一个空结构,所有字段为空,在火花中为空

为啥这个 NSString 在 FireBase 查询块中为空?

复杂类型在 ApiController 参数中为空

为啥 recyclerview$adapter 在片段中为空

检查 DateTime 类型的值是不是在视图中为空,如果为空则显示空白