Null как значение в HttpRuntime.Cache.Add - PullRequest
5 голосов
/ 22 марта 2012

Я хочу сохранить 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: значение не может быть нулевым.

Любая идея, если это возможно, или мне нужно использовать другую структуру данных для хранения нулевых значений и поиска позже?

Ответы [ 3 ]

6 голосов
/ 22 марта 2012

Вы можете использовать свое собственное значение "null" для помещения в кеш.Например,

private static Info NULL_INFO = new Info();

Тогда вы можете использовать это вместо нуля в HttpRuntime.Cache.Add и позже, после извлечения из кэша, проверьте, что вы не получили ваш 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
1 голос
/ 22 марта 2012

Недавно я написал в блоге о том, как часто злоупотребляют ключевым словом null, что приводит к путанице такого рода. В вашем конкретном случае я хотел бы использовать тип опции , чтобы указать на отсутствие или присутствие данных, а не на ноль.

У меня есть простая реализация типа 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...
}
0 голосов
/ 22 марта 2012

Вам просто нужно проверить, не является ли значение, полученное из вашего источника данных, нулевым, прежде чем пытаться добавить его обратно в кэш, см. Ниже:

        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, поэтому вам не нужно сохранять значение null в кэше.Хранение null значений в кэше на самом деле бесполезно, поэтому есть причина, по которой среда не позволяет вам этого делать.

Также в качестве небольшого дополнения было бы неплохо создатьваш ключ кеша один раз, затем повторно используйте его, а не восстанавливайте каждый раз, когда он используется.Например:

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

Тогда просто используйте:

HttpRuntime.Cache[key]

При доступе к нему ваш код будет менее подвержен ошибкам при опечатке.

...