Сохранить нулевое значение в System.Web.HttpContext.Current.Cache

1

В приложении MVC мы предполагаем динамически загружать некоторые строки из базы данных. В основном словарь словаря <string,string>. Загрузка каждого текста каждый раз из базы данных приведет к уничтожению приложения, поэтому эти тексты обычно вытаскиваются из БД только один раз, а затем сохраняются в кеше (а именно Web.HttpContext.Current.Cache). Существуют также тексты по умолчанию, которые жестко закодированы, и они будут использоваться, если в базе данных ничего не найдено. Чтобы сделать вещи более простыми, я бы также поместил эти тексты по умолчанию в кеш.

Логика такова:

  1. Попробуйте получить текст из кеша и верните его, если он найдет.

  2. Если в кеше не было текста, попробуйте вытащить его из базы данных, и если он будет найден, сохраните его в кеш и верните его.

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

Если я правильно понимаю, единственный способ проверить, установлен ли ключ в Web.HttpContext.Current.Cache, путем сравнения его значения с нулем. Моя проблема заключается в том, что не совсем маловероятно, чтобы текст по умолчанию был пустым. Поэтому, если я поместил это в кеш, я не буду знать, что ключ был установлен, и я попытаюсь вытащить несуществующее значение из базы данных каждый раз, когда текст понадобится.

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

Итак, есть ли способ определить, установлен ли ключ в Web.HttpContext.Current.Cache когда назначенное значение является нулевым?

Теги:
asp.net-mvc
caching

3 ответа

2
Лучший ответ

StriplingWarrior избил меня до удара, но я согласен с тем, что он сказал: просто оберните то, что вы храните в сложном виде, чтобы вы могли выполнить нулевую проверку. Обычно для этого используется Nullable<T>, но вы не можете использовать тип Nullable для вещей, которые уже считаются нулевыми, например, строки.

Вот практический пример:

Определите простой класс-оболочку:

public class CacheEntry<T>
{
    public T Value { get; private set; }

    public CacheEntry(T value)
    {
        Value = value;
    } 
}

И затем используйте его!

System.Web.HttpContext.Current.Cache.Insert("name", new CacheEntry<string>("Marcin"));

var name = (CacheEntry<string>) System.Web.HttpContext.Current.Cache.Get("name");
if (name != null)
{
    Console.WriteLine(name.Value);
}
  • 0
    Я не уверен, должен ли я принять ответ StriplingWarrior или ваш. Я имею в виду, он ответил первым, его ответ правильный и в целом такой же, как и у вас, но ваш содержит простой и понятный код (который мне нравится больше, и я собираюсь его использовать).
2

null очень сильно используется большинством разработчиков С#. Если вы признаете, что эти значения являются необязательными (это значит, что они могут быть или не быть), вы можете захотеть сделать ваши записи в кеш файлами определенного типа, который обертывает фактический тип, который вы храните. Таким образом, получение нулевого значения означает, что нет записи, тогда как получение ненулевого значения, которое имеет свойство null Value на нем, означает, что оно существует в кеше, но его значение равно null.

Кстати, я работал над библиотекой, чтобы представлять именно такую оболочку. Он по-прежнему находится в альфа-фазах на данный момент, но, по крайней мере, для этой цели он должен быть безопасным в использовании. Вы можете получить его у Nuget под названием "CallMeMaybe".

object result = HttpContext.Current.Cache.Get(key);
if(result != null)
{
    return ((Maybe<string>)result).Else(() => null);
}
var value = Maybe.From(GetValueFromDb());
HttpContext.Current.Cache.Add(key, value, ...);
return value;

Другой вариант - использовать MemoryCache напрямую, и я думаю, что в настоящее время поддерживает HttpContext.Current.Cache, но предоставляет дополнительные методы, такие как GetCacheItem.

1

Если вы должны сохранить нуль в том, что не различает нули и не найденные условия, сохраните объект "active null" для представления нулевого значения, которое вы фактически добавили:

private static readonly object ActiveNull = new object();

public bool GetIfPresent(string key, out object value)
{
    object fromCache = Web.HttpContext.Current.Cache.Get(key);
    if(fromCache == null)
    {
      //failed to obtain.
      value = null;
      return false;
    }
    if(ReferenceEquals(fromCache, ActiveNull))
    {
      //obtained value representing null.
      value = null;
      return true;
    }
    value = fromCache;
    return true;
}

public void AddToCache(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
{
  Web.HttpContext.Current.Cache.Add(key, value ?? ActiveNull, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback);
}
  • 0
    Подумав еще немного о проблеме, я тоже пришел к этой идее, но, прочитав другие ответы (по разным причинам я не мог этого сделать до сих пор), обертка звучит как еще лучшее решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню