2011-12-22 39 views
6

Tôi có hai bộ dữ liệu (Danh sách các đối tượng phức tạp hoặc dữ liệu SQL - LINQ to Entities) trong đó cố gắng tìm giao điểm của hai tập dữ liệu. Cụ thể một giao điểm của tài sản phức tạp, "HashData" như bên dưới:Giao điểm của hai bộ (Danh sách) của dữ liệu

SQL data

Tập ở bên trái có khả năng là khoảng 10000 dòng, trong khi các thiết lập ở bên phải luôn luôn là một tập hợp con của khoảng 100 hàng. Tôi nhận ra rằng nếu tôi sắp xếp tập hợp bên trái bằng "Hashdata" khi lưu trữ, thực hiện tìm kiếm nhanh hơn rất nhiều bằng cách sử dụng một số thuật toán tìm kiếm nhị phân, tuy nhiên tôi không thể làm điều này vì lý do không phù hợp với câu hỏi.

Tập dữ liệu nhỏ hơn không bao giờ được lưu trữ trong SQL (chỉ được hiển thị trong bảng SQL bên dưới cho mục đích giải thích). Nó được trình bày trong một List<ShowData> khi chạy.

Hiện nay tôi đang làm một vòng thảm hại qua các dữ liệu và kết hợp như thế này (nơi recording là danh sách 100 hàng và ShowData là danh sách 10000 hàng):

List<ShowData> ShowData = (from showData in context.ShowDatas 
          where (showData.Show.Id == advert.Id) 
          orderby showData.HashData ascending 
          select showData).ToList(); 

foreach (ShowData recording in recordingPoints) { 
    foreach (ShowData actual in ShowData) { 
     if (recording.HashData == actual.HashData) { 
     } 
    } 
} 

Vì vậy, về cơ bản những gì im cố gắng phải làm là:

Trả về danh sách các đối tượng ShowData (tập lớn) trong đó bất kỳ HashData (từ tập hợp nhỏ) nào được tìm thấy trong ShowData BUT trong truy vấn ban đầu LINQ to Entity đến DB.

tôi trở nên thân thiết với:

private IEnumerable<ShowData> xyz(List<ShowData> aObj, List<ShowData> bObj) 
    { 
     IEnumerable<string> bStrs = bObj.Select(b => b.HashData).Distinct(); 
     return aObj.Join(bStrs, a => a.HashData, b => b, (a, b) => a); 
    } 

Trả lời

6

Vì bạn đang sử dụng IEnumerable, bạn có thể sử dụng phương pháp Intersect mở rộng thay vì tham gia. Nếu bạn muốn trả về tập hợp lớn, bạn sẽ muốn cắt kết quả của truy vấn tập hợp lớn với tập hợp nhỏ hơn. Bạn sẽ cần phải viết một IEquality Comparer như ở đây: http://msdn.microsoft.com/en-us/library/bb355408.aspx để so sánh đối tượng của bạn, sau đó gọi phương thức Intersect mở rộng:

return bStrs.Intersect(aObj, new MyEqualityComparer()); 
+0

hi Josh , tôi đã thử điều này: 'công bool Equals (ShowData x, ShowData y) { // Kiểm tra xem các đối tượng so sánh có tham chiếu cùng một dữ liệu hay không. nếu (Object.ReferenceEquals (x, y)) trả về true; // Kiểm tra xem có bất kỳ đối tượng nào được so sánh không. if (Object.ReferenceEquals (x, null) || Object.ReferenceEquals (y, null)) trả về false; // Kiểm tra xem các thuộc tính của sản phẩm có bằng nhau hay không. return x.HashData == y.HashData; } ' – user1112324

+0

nhưng không chắc cách biên dịch này khi tôi gặp lỗi: iEnumerable không chứa định nghĩa cho Intersect – user1112324

+0

@ user1112324 - Bạn có chắc là bạn đã đưa câu lệnh 'using' cho 'System.Linq' và ' System.Collections.Generic '? Giao lộ chắc chắn là một phương pháp mở rộng của IEnumerable . –

1

Something như thế này có thể làm việc (cảnh báo chưa được kiểm tra):

private IEnumerable<ShowData> xyz(List<ShowData> aObj, List<ShowData> bObj) 
{ 
    return aObj.Where(sd1 => bObj.Select(sd2 => sd2.HashData).Contains(sd1.HashData)); 
} 
+0

Hi, tôi đã thử điều này ở trên nhưng tôi nhận được kết quả khác nhau cho khi tôi lặp qua hai bộ và đếm các trận đấu (recording.HashData == actual.HashData) so với khi tôi chạy phương pháp của bạn ở trên: IEnumerable contains = xyz (ShowData, recordingPoints); int trả về = chứa.Đếm(); – user1112324

+0

nó có thể gây ra phương pháp của bạn chỉ nhận được các giá trị duy nhất (tức là nếu nó đã có trong bộ trả lại không readd nó). Tôi cần nó được readded ngay cả khi nó đã có – user1112324

+0

câu trả lời của Josh sẽ có khả năng làm việc tốt hơn cho các mục đích của bạn (mặc dù tôi không chắc chắn nếu Intersect chỉ cung cấp kết quả khác biệt hay không cũng). –

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