Найти ключ с помощью лямбда-выражения в кэше HttpContext.Current.Items
У меня есть кэш по запросу, реализованный с использованием HttpContext.Current.Items, как это:
private static readonly Lazy<CacheCurrentCall> lazy =
new Lazy<CacheCurrentCall>(() => new CacheCurrentCall());
public static CacheCurrentCall Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if (!items.Contains("CacheCurrentCall"))
{
items["CacheCurrentCall"] = new CacheCurrentCall();
}
return items["CacheCurrentCall"] as CacheCurrentCall;
}
}
private CacheCurrentCall()
{
}
public void Add<T>(T o, string key, int cacheDurationSeconds = 0)
{
HttpContext.Current.Items.Add(key, o);
}
public void Clear(string key)
{
HttpContext.Current.Items.Remove(key);
}
public bool Exists(string key)
{
return HttpContext.Current.Items[key] != null;
}
public bool Get<T>(string key, out T value)
{
try
{
if (!Exists(key))
{
value = default(T);
return false;
}
value = (T)HttpContext.Current.Items[key];
}
catch
{
value = default(T);
return false;
}
return true;
}
Теперь мне нужно удалить все ключи, начиная с определенной строки, и поэтому я думал о методе, подобном этому
public IEnumerable<string> GetKey (Func<string, bool> condition)
а затем циклически просматривая результаты и очищая их (я мог даже очистить непосредственно в Clear, принимая лямбда-выражение, я полагаю). Но я теряюсь, пытаясь реализовать такой метод, если это возможно на самом деле.
Любая помощь?
Спасибо
Редактировать:
Servy, я пытался (слепо пробовал некоторые вещи, но более или менее следуя этому пути)
public IEnumerable<string> GetKeys(Func<string, bool> condition)
{
List<string> list = new List<string>();
foreach (var key in HttpContext.Current.Items.Keys)
{
if (condition(key as string))
{
list.Add(key as string);
}
}
return list;
}
Но я получаю:
В экземпляре объекта не задана ссылка на объект
Я сейчас попробую pswg, что помимо того, что это работает, на мой взгляд, намного элегантнее.
Второе редактирование:
Мне нужно было немного изменить решение PSWG. Я не храню строки в кеше, но другие объекты, поэтому я использую это сейчас
public IEnumerable<string> GetKeys (Func<string, bool> condition)
{
return HttpContext.Current.Items
.Cast<DictionaryEntry>()
.Where(e => e.Key is string && condition(e.Key as string))
.Select(e => e.Key as string);
}
И вызов для очистки кэша, например, этот
public void ClearCache()
{
var ownedItemSummaryKeys = CacheCurrentCall.Instance.GetKeys(k => k.Contains("OwnedItemSummaryCurrent"));
foreach (var ownedItemSummaryKey in ownedItemSummaryKeys.ToList())
{
CacheCurrentCall.Instance.Clear(ownedItemSummaryKey);
}
}
1 ответ
Items
собственность IDictionary
так что вам придется сделать это:
public IEnumerable<string> GetKey (Func<string, bool> condition)
{
return HttpContext.Current.Items
.Cast<DictionaryEntry>()
.Where(e => e.Key is string &&
e.Value is string &&
condition(e.Key as string))
.Select(e => e.Value as string);
}
или в синтаксисе запроса:
public IEnumerable<string> GetKey (Func<string, bool> condition)
{
return
from e in HttpContext.Current.Items.Cast<DictionaryEntry>()
where e.Key is string &&
e.Value is string &&
condition(e.Key as string)
select e.Value as string;
}
Обновление я пропустил - прочитал вопрос. Я думал, что вы хотите выбрать значения на основе определенных критериев ключей. Если вы хотите выбрать только ключи, на самом деле это немного проще:
public IEnumerable<string> GetKey (Func<string, bool> condition)
{
return HttpContext.Current.Items.Keys
.OfType<string>()
.Where(condition);
}
Или в синтаксисе запроса:
public IEnumerable<string> GetKey (Func<string, bool> condition)
{
return
from k in HttpContext.Current.Items.Keys.OfType<string>()
where condition(k)
select k;
}