2014-11-21 149 views
6

我已經看到如何轉換ConcurrentDictionary to a Dictionary,但我有一個字典,並希望轉換爲ConcurrentDictionary。我該怎麼做?...更好的是,我可以將鏈接語句設置爲ConcurrentDictionary?如何將字典轉換爲ConcurrentDictionary?

var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x); 
+0

什麼您使用的是LINQ提供程序? Query()或Select()是IQueryable還是IEnumerable的結果? – 2014-11-21 14:57:52

回答

14

使用 ConcurrentDictionary<TKey, TValue> Constructor (IEnumerable<KeyValuePair<TKey, TValue>>) constructor它可以接受一個字典對象,如:

Dictionary<int, string> dictionary = new Dictionary<int, string>(); 
dictionary.Add(1,"A"); 
dictionary.Add(2, "B"); 

ConcurrentDictionary<int,string> concurrentDictionary = 
      new ConcurrentDictionary<int, string>(dictionary); 

我可以設置LINQ語句作爲ConcurrentDictionary?

No. 你不能。 。沒有可用的擴展方法在LINQ中創建ConcurrentDictionary。您可以創建自己的擴展方法,也可以在預測結果的同時在LINQ查詢中使用構造函數ConcurrentDictionary

+0

那麼你可以使用LINQ將結果投影到字典中,但是你必須編寫自己的'ToConcurrentDictionary'擴展方法來完成它。 (你可能能夠擺脫中級詞典並直接使用'foreach'並插入一個鍵和值選擇器委託)。 – 2014-11-21 14:51:20

+0

你*可以*使用LINQ,與你提到的構造函數。使用所需的鍵和值從原始可枚舉中創建一個KeyValuePair,然後將其傳遞給構造函數,例如。 myEnumerable = ... Select(item => new KeyValuePair(item.Id,item); ...新的ConcurrentDictionary(myEnumerable);'不需要ForEach,儘管擴展方法會使代碼稍微更清潔 – 2014-11-21 14:52:44

2

一個LINQ到對象的語句是最終一個IEnumerable,所以你可以把它傳遞給ConcurrentDictionary構造函數,例如:

var customers = myCustomers.Select(x => new KeyValuePair(x.id, x)); 
var dictionary=new ConcurrentDictionary(customers); 

這可能不與其他供應商合作。例如,Linq to Entities將整個LINQ語句轉換爲SQL,並且無法投影到KeyValuePair。在這種情況下,你可能需要調用AsEnumerable()或迫使IQueryable的執行任何其他的方法,如:

var customers = _customerRepo.Customers.Where(...) 
          .AsEnumerable() 
          .Select(x => new KeyValuePair(x.id, x)); 
var dictionary=new ConcurrentDictionary(customers); 

Select()不帶參數不是一個IEnumerable或IQueryable的方法,所以我想這是由其他一些提供一種方法, ORM。如果Select()返回一個IEnumerable,你可以使用第一個選項,否則你可以使用AsEnumerable()

+0

Note你可以做AsEnumerable()'[在可枚舉]上(http:// msdn。microsoft.com/en-us/library/vstudio/bb335435(v=vs.100).aspx),它不會傷害任何東西。 – 2014-11-21 15:23:33

4

爲什麼不寫自己的擴展方法:

public static class ConcurrentDictionaryExtensions { 
    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (keySelector == null) throw new ArgumentNullException("keySelector"); 
     if (elementSelector == null) throw new ArgumentNullException("elementSelector"); 

     ConcurrentDictionary<TKey, TElement> d = new ConcurrentDictionary<TKey, TElement>(comparer); 
     foreach (TSource element in source) 
      d.TryAdd(keySelector(element), elementSelector(element)); 

     return d; 
    } 

    public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { 
     return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null); 
    } 

    public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) { 
     return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer); 
    } 

    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) { 
     return ToConcurrentDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null); 
    } 

    internal class IdentityFunction<TElement> { 
     public static Func<TElement, TElement> Instance 
     { 
      get { return x => x; } 
     } 
    } 

} 

只需從.Net framework採用的代碼。

0

或者只是一個有方法:

private ConcurrentDictionary<TKey, TValue> ToConcurrent<TKey, TValue>(Dictionary<TKey, TValue> dic) { 
     return new ConcurrentDictionary<TKey, TValue>(dic); 
    } 

然後執行:

var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x); 
var concurrentDic = ToConcurrent(customers); 

就個人而言,我與擴展的方法,我剛剛更新會...