2012-04-18 42 views
75

.ToLookup<TSource, TKey> trả lại số ILookup<TKey, TSource>. ILookup<TKey, TSource> cũng thực hiện giao diện IEnumerable<IGrouping<TKey, TSource>>.Tại sao ToLookup và GroupBy lại khác nhau?

.GroupBy<TSource, TKey> trả về số IEnumerable<IGrouping<Tkey, TSource>>.

ILookup có thuộc tính chỉ mục tiện dụng, vì vậy nó có thể được sử dụng theo cách giống như từ điển (hoặc tra cứu), trong khi GroupBy thì không. GroupBy không có người lập chỉ mục là một nỗi đau để làm việc; khá nhiều cách duy nhất bạn có thể sau đó tham chiếu đối tượng trả về là bằng cách lặp qua nó (hoặc sử dụng phương pháp mở rộng LINQ khác). Nói cách khác, bất kỳ trường hợp nào mà GroupBy hoạt động, ToLookup cũng sẽ hoạt động.

Tất cả điều này để lại cho tôi câu hỏi tại sao tôi lại bận tâm với GroupBy? Tại sao nó nên tồn tại?

+5

'GroupBy' là' IQuerable', 'ILookup' không phải là – Magnus

+5

groupby doesn' t liệt kê danh sách [ToLookup] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable.tolookup.aspx) liệt kê nó giống như cách ToList/ToArray – Aducci

+3

Tôi đã đề cử điều này để mở lại vì câu hỏi được cho là trùng lặp là về * IGrouping * thay vì * GroupBy * và * ILookup * thay vì * ToLookup *. Sự khác biệt giữa những khác biệt này với sự khác biệt giữa chúng. Điều này nên được rõ ràng từ sự khác biệt trong các câu trả lời giữa các câu hỏi. – Sam

Trả lời

130

tại sao tôi lại bận tâm với GroupBy? Tại sao nó nên tồn tại?

Điều gì xảy ra khi bạn gọi ToLookup trên một đối tượng đại diện cho một bảng cơ sở dữ liệu từ xa với hàng tỷ hàng trong đó?

Hàng tỷ được gửi qua dây và bạn tạo bảng tra cứu cục bộ.

Điều gì xảy ra khi bạn gọi GroupBy trên một đối tượng như vậy?

Đối tượng truy vấn được tạo; kết thúc câu chuyện.

Khi mà đối tượng truy vấn được liệt kê sau đó phân tích các bảng được thực hiện trên máy chủ cơ sở dữ liệu và kết quả nhóm được gửi trở lại theo yêu cầu một vài tại một thời điểm.

Về mặt logic, chúng giống nhau nhưng ý nghĩa hiệu suất của mỗi khác hoàn toàn khác nhau. Gọi ToLookup nghĩa là Tôi muốn bộ nhớ cache của toàn bộ nội dung hiện được sắp xếp theo nhóm. Gọi GroupBy có nghĩa là "Tôi đang xây dựng một đối tượng để đại diện cho câu hỏi 'những thứ này sẽ trông như thế nào nếu tôi tổ chức chúng theo nhóm?'"

+3

Áp phích không ' t cụ thể nhắm mục tiêu một đại diện 'IQueryable '. Câu trả lời của bạn bao gồm tình huống đó, nhưng khi nó chỉ đơn giản là ol 'IEnumerable ' (LINQ-to-Objects), có vẻ như không có lý do gì để sử dụng cái kia, đó là điều tôi tin @Shlomo đang cố gắng nhận được ở. * Không * trường hợp 'IQueryable ', nhưng trường hợp LINQ-to-Objects. – casperOne

+0

Nó đánh tôi như là có lợi cho LINQ là nhất quán, nếu có thể. Tôi nghĩ rằng việc chứng minh tính hữu ích của nó trong LINQ-to-SQL là đủ để biện minh cho việc rời khỏi nó trong LINQ-to-Objects. – Brian

+19

@casperOne: Tôi nghĩ bạn đã không hiểu điểm của tôi. Ngay cả trong trường hợp LINQ-to-objects, gọi GroupBy * vẫn * không lặp qua bộ sưu tập. (Như Aducci đã chỉ ra trong câu trả lời mà bạn đã xóa.) Đó là một sự khác biệt cơ bản. –

12

Cả hai đều giống nhau nhưng được sử dụng trong các trường hợp khác nhau. .ToLookup() trả về một đối tượng sẵn sàng để sử dụng đã có tất cả các nhóm (nhưng không phải là nội dung của nhóm) háo hức nạp. Mặt khác, .GroupBy() trả về một chuỗi các nhóm được tải chậm.

Các nhà cung cấp LINQ khác nhau có thể có các hành vi khác nhau để tải trọng mong muốn và lười biếng của các nhóm. Với LINQ-to-Object nó có thể tạo ra sự khác biệt nhỏ, nhưng với LINQ-to-SQL (hoặc LINQ-to-EF, vv), hoạt động nhóm được thực hiện trên máy chủ cơ sở dữ liệu thay vì máy khách, và vì vậy bạn có thể muốn để thực hiện lọc bổ sung trên khóa nhóm (tạo mệnh đề HAVING) và sau đó chỉ nhận một số nhóm thay vì tất cả chúng. .ToLookup() sẽ không cho phép các ngữ nghĩa như vậy vì tất cả các mục được háo hức nhóm lại.

70

Nói cách LINQ cấp thế giới đơn giản:

  • ToLookup() - ngay lập tức thực hiện
  • GroupBy() - thi công chậm
Các vấn đề liên quan