我已经看到如何将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);
使用
可以接受字典对象的ConcurrentDictionary<TKey, TValue> Constructor (IEnumerable<KeyValuePair<TKey, TValue>>)
构造函数,例如:
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 吗?
不,你不能。. ConcurrentDictionary
在 LINQ中没有可用于创建的扩展方法。您可以创建自己的扩展方法,也可以ConcurrentDictionary
在投影结果时在 LINQ 查询中使用构造函数。
为什么不编写自己的扩展方法:
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 框架中的代码。
LINQ-To-Objects 语句最终是一个 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()
或者只是一个有方法:
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);
就个人而言,我将使用我刚刚更新的扩展方法......