2014-11-21 19 views
6

Tôi đã thấy cách chuyển đổi ConcurrentDictionary to a Dictionary, nhưng tôi có từ điển và muốn chuyển đổi thành ConcurrentDictionary. Làm cách nào để làm điều đó? ... tốt hơn, tôi có thể đặt câu lệnh liên kết thành ConcurrentDictionary không?Làm cách nào để chuyển đổi từ điển sang ConcurrentDictionary?

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

gì Nhà cung cấp LINQ bạn đang sử dụng? Là kết quả của 'Truy vấn()' hoặc 'Chọn()' một IQueryable hoặc một IEnumerable? –

Trả lời

14

Sử dụng ConcurrentDictionary<TKey, TValue> Constructor (IEnumerable<KeyValuePair<TKey, TValue>>) constructor mà có thể chấp nhận một đối tượng từ điển như:

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

tôi có thể thiết lập báo cáo kết quả LINQ là một ConcurrentDictionary?

No. Bạn không thể. . Không có phương pháp mở rộng nào để tạo ConcurrentDictionary trong LINQ. Bạn có thể tạo phương thức mở rộng của riêng mình hoặc bạn có thể sử dụng hàm tạo ConcurrentDictionary trong truy vấn LINQ của bạn trong khi chiếu kết quả.

+0

Vâng, bạn có thể chiếu kết quả vào một từ điển bằng LINQ, nhưng bạn sẽ phải viết phương thức mở rộng 'ToConcurrentDictionary' của riêng bạn để làm điều đó. (Bạn có thể loại bỏ từ điển trung gian và chèn trực tiếp bằng cách sử dụng 'foreach' và tham gia khóa đại biểu và giá trị chọn). –

+0

Bạn * có thể * sử dụng LINQ, với hàm tạo mà bạn đã đề cập. Tạo một KeyValuePair từ bản gốc có thể đếm được với khóa và giá trị mong muốn, sau đó chuyển nó tới hàm tạo, ví dụ: 'myEnumerable = ... Chọn (item => new KeyValuePair (item.Id, item); ... new ConcurrentDictionary (myEnumerable);'. Không cần ForEach, mặc dù phương thức mở rộng sẽ làm cho mã hơi sạch hơn –

2

Một LINQ-To-Objects tuyên bố là cuối cùng một IEnumerable để bạn có thể vượt qua nó để các nhà xây dựng ConcurrentDictionary, ví dụ:

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

này có thể không làm việc với các nhà cung cấp khác. Ví dụ: LINQ to Entities, chuyển đổi toàn bộ câu lệnh LINQ thành SQL và không thể chiếu sang KeyValuePair. Trong trường hợp này bạn có thể phải gọi AsEnumerable() hoặc bất kỳ phương pháp khác mà buộc IQueryable để thực hiện, ví dụ:

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

Select() không có đối số không phải là một phương pháp IEnumerable hoặc IQueryable vì vậy tôi cho rằng đó là một phương pháp được cung cấp bởi một số khác ORM. Nếu Select() trả về một IEnumerable bạn có thể sử dụng tùy chọn đầu tiên, nếu không bạn có thể sử dụng AsEnumerable()

+0

Lưu ý bạn có thể làm 'AsEnumerable()' [trên một số đếm] (http: // msdn.microsoft.com/en-us/library/vstudio/bb335435(v=vs.100).aspx) và nó sẽ không làm tổn thương gì cả. –

4

Tại sao không viết phương pháp khuyến nông của riêng bạn:

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

} 

Đơn giản chỉ cần thông qua mã từ .Net framework.

0

Hoặc chỉ cần một có phương pháp:

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

và sau đó làm:

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

Cá nhân, tôi sẽ có phương pháp mở rộng mà tôi chỉ cập nhật ...

Các vấn đề liên quan