/ / Linq Query On IDictionaryEnumerator Možné? - c #, asp.net, linq, ukladanie do pamäte cache

Linq Query na IDictionaryEnumerator možný? - c #, asp.net, linq, ukladanie do vyrovnávacej pamäte

Potrebujem vymazať položky z vyrovnávacej pamäte, ktoré obsahujú konkrétny reťazec v kľúči. Začal som s nasledujúcim a myslel som, že by som mohol urobiť linq dotaz

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

Ale môžem "t? Dúfal som, že niečo podobné urobím."

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

Akékoľvek nápady, ako by som to mohol dosiahnuť?

odpovede:

10 pre odpoveď č. 1

Enumerátor vytvorený pomocou Cache generuje DictionaryEntry objektov. Ďalej, a Cache môže mať len string kľúča.

Takto môžete napísať:

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

Toto je však potenciálne pomalá operáciakeď je vyrovnávacia pamäť veľká: pamäť cache nie je navrhnutá tak, aby sa používala takto. Mali by ste sa pýtať sami seba, či nie je možný a preferovaný alternatívny dizajn. Prečo potrebujete odstrániť niekoľko kľúčov pamäte cache naraz a prečo nie ste zoskupení kľúčov pamäte cache podreťazcom?


5 pre odpoveď № 2

Vzhľadom k tomu, Cache je IEnumerable, môžete voľne použiť všetky metódy LINQ, ktoré potrebujete. Jediná vec, ktorú potrebujete, je odovzdať ju IEnumerable <DictionaryEntry>:


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

Teraz keysQuery je non-striktné zhromažďovanie všetkých kľúčov od "subcat". Ale ak potrebujete odstrániť tieto položky z cache najjednoduchší spôsob je jednoducho použiť foreach vyhlásenie.


2 pre odpoveď č. 3

Nemyslím si, že je to skvelý nápad chodiť po celej cache v každom prípade, ale mohli by ste to urobiť iným spôsobom ako 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
}
}
}

aby ste to urobili s LINQ, môžete urobiť niečo ako:

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

a používať ako:

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