2014-11-21 138 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); 

就个人而言,我与扩展的方法,我刚刚更新会...