Linq Query On IDictionaryEnumerator Maybe?

I need to clear items from the cache containing a specific line in the key. I started with the following and thought I could execute the linq request

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

But I can not? I was hoping to do something like

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

Any ideas on how I could achieve this?

+4
source share
3 answers

The enumerator created by Cache generates DictionaryEntry objects. In addition, Cache can only have string keys.

So you can write the following:

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

However, this is a potentially slow operation when the cache is large: the cache is not intended to be used that way. You should ask yourself if alternative design is not impossible and preferable. Why do you need to delete several cache keys at once, and why don't you group cache keys by substring?

+10
source

Since Cache is IEnumerable, you are free to use all the LINQ methods you need. The only thing you need is to pass it to an IEnumerable <DictionaryEntry>:

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

KeysQuery is now a non-strict set of all keys, starting with "subcat". But if you need to delete such entries from the cache, the easiest way is to simply use the foreach statement.

+5
source

I don't think it is a good idea to cache everything, but you could do it non-LINQ with something like:

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

to do this with LINQ, you can do something like:

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

and use as:

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

Source: https://habr.com/ru/post/1337937/


All Articles