我已经看到如何将ConcurrentDictionary转换为Dictionary,但我有一个字典并想将其转换为ConcurrentDictionary。我该怎么做?更好的是,我能否将链接语句设置为ConcurrentDictionary?
var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x);
我已经看到如何将ConcurrentDictionary转换为Dictionary,但我有一个字典并想将其转换为ConcurrentDictionary。我该怎么做?更好的是,我能否将链接语句设置为ConcurrentDictionary?
var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x);
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吗?
不行。无法实现。在LINQ中没有可用的扩展方法来创建ConcurrentDictionary
。您可以创建自己的扩展方法,或者在投影结果时在LINQ查询中使用ConcurrentDictionary
构造函数。
ToConcurrentDictionary
扩展方法来完成它。(你可能可以通过使用foreach
并采用键和值选择器委托来消除中间字典,并直接插入)。 - Scott ChamberlainmyEnumerable= ... Select(item=>new KeyValuePair(item.Id,item); ... new ConcurrentDictionary(myEnumerable);
。不需要ForEach,尽管扩展方法可以使代码稍微更清晰一些。 - Panagiotis Kanavos 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 ?? EqualityComparer<TKey>.Default);
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框架中借鉴而来。
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()
方法。
AsEnumerable()
操作,并不会对其造成任何影响。 - Scott Chamberlain或者只是一个 have 方法:
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);
就我个人而言,我会选择刚刚更新的扩展方法...
Query()
或Select()
的结果是IQueryable还是IEnumerable? - Panagiotis Kanavos