2011-02-01 8 views
4

キーから特定の文字列を含むアイテムをキャッシュから消去する必要があります。私は以下から始めて、私はlinqのクエリを行うことができるかもしれないと思ったLinqクエリIDictionaryEnumeratorで可能ですか?

var enumerator = HttpContext.Current.Cache.GetEnumerator(); 

私はできない?

var enumerator = HttpContext.Current.Cache.GetEnumerator().Key.Contains("subcat"); 

私はこれをどのように達成することができますか?

私はとにかくをキャッシュ全体 を歩くのは素晴らしいアイデアだとは思わないが、あなたのようなもので、それを非LINQを行うことができ
+5

脇にある:キャッシュ全体を列挙することは、本質的にビジー状態のサイトでは悪い考えです... –

+0

あなたのことをすべて聞いています...図面ボードに戻る – leen3o

答えて

10

Cacheによって作成された列挙子は、DictionaryEntryオブジェクトを生成します。さらに、Cacheにはstringキーしか含まれていない可能性があります。

したがって、次のように記述することができます。

var httpCache = HttpContext.Current.Cache; 
var toRemove = httpCache.Cast<DictionaryEntry>() 
    .Select(de=>(string)de.Key) 
    .Where(key=>key.Contains("subcat")) 
    .ToArray(); //use .ToArray() to avoid concurrent modification issues. 

foreach(var keyToRemove in toRemove) 
    httpCache.Remove(keyToRemove); 

キャッシュが大きい場合しかし、これは潜在的に遅い操作です:キャッシュがこのように使用するように設計されていません。あなたは代替設計が可能ではなく、好ましいものであるかどうか自問するべきです。一度にいくつかのキャッシュキーを削除する必要があります。なぜ、キャッシュキーを部分文字列でグループ化しないのですか?

+0

「キャッシュキーを部分文字列でグループ化する」とは何が得られましたか? –

2

:あなたができるLINQでそれを行うために

var iter = HttpContext.Current.Cache.GetEnumerator(); 
    using (iter as IDisposable) 
    { 
     while (iter.MoveNext()) 
     { 
      string s; 
      if ((s = iter.Key as string) != null && s.Contains("subcat")) 
      { 
       //... let the magic happen 
      } 
     } 
    } 

何かのように:

public static class Utils 
{ 
    public static IEnumerable<KeyValuePair<object, object>> ForLinq(this IDictionaryEnumerator iter) 
    { 
     using (iter as IDisposable) 
     { 
      while (iter.MoveNext()) yield return new KeyValuePair<object, object>(iter.Key, iter.Value); 
     } 
    } 
} 

と同様に使用します。

var items = HttpContext.Current.Cache.GetEnumerator().ForLinq() 
     .Where(pair => ((string)pair.Key).Contains("subcat")); 
+0

上記のおかげで、感謝しました - しかし、特定のキーで始まったキャッシュされたアイテム...? – leen3o

+1

私は心配する必要はありませんが、非常に良い答えではありません。 –

+0

これはおそらく最も合理的な答えです。 –

5

ので、キャッシュはIEnumerableで、必要なすべてのLINQメソッドを自由に適用できます。あなたが必要とする唯一のものは、IEnumerableを<DictionaryEntry>にキャストすることです:

 

var keysQuery = HttpContext.Current.Cache 
    .Cast<DictionaryEntry>() 
    .Select(entry => (string)entry.Key) 
    .Where(key => key.Contains("subcat")); 
 

今keysQueryは「SUBCAT」から始まるすべてのキーの非厳格なコレクションです。しかし、キャッシュからそのようなエントリを削除する必要がある場合、最も簡単な方法はforeach文を使用することです。

+0

これは以下よりずっと効果的でしょうか? – leen3o

+0

「下に」あるものはわかりませんが、単純なforeachより効率的なソリューションはほとんど存在しません。 –

+0

いいえ、すべてのソリューションはキャッシュ全体を列挙し、すべてのキーを調べなければならないという意味では遅いです。 –

関連する問題