2011-12-22 26 views
6

Mam dwa zestawy danych (listy złożonych obiektów lub danych SQL - LINQ do encji), w których im próbuje znaleźć przecięcie dwóch zestawów danych. Konkretnie skrzyżowanie nieruchomości Complex „HashData” jak widać poniżej:Przecięcie dwóch zestawów (list) danych

SQL data

Zestaw po lewej to prawdopodobnie około 10000 wierszy, podczas zbioru po prawej stronie jest zawsze podzbiorem około 100 wydziwianie. Zdaję sobie sprawę, że jeśli posortuję zestaw po lewej stronie "Hashdata" podczas jego przechowywania, wyszukiwanie będzie dużo szybsze przy użyciu jakiegoś algorytmu binarnego wyszukiwania, jednak nie mogę tego zrobić z powodów niezwiązanych z pytaniem.

Mniejszy podzbiór danych nigdy nie jest przechowywany w SQL (pokazany tylko w poniższej tabeli SQL w celach wyjaśniających). Jest prezentowany w List<ShowData> w czasie wykonywania.

W tej chwili robię żałosne pętlę poprzez danych i dopasowanie następująco (gdzie recording lista 100 wierszy i ShowData lista 10000 wiersz):

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) { 
     } 
    } 
} 

Więc w zasadzie to, co im próbuje Aby to zrobić, należy:

Zwrócić listę obiektów ShowData (duży zestaw), gdzie dowolne dane HashData (z małego zestawu) znajdują się w ShowData, ale w LINQ do obiektu początkowego zapytania do bazy danych.

mam blisko z:

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

Odpowiedz

6

Ponieważ używasz IEnumerable, można użyć metody Extension Przecięcie zamiast Dołącz. Jeśli chcesz zwrócić duży zestaw, powinieneś przeciąć wynik dużego zestawu zapytań z mniejszym zestawem. trzeba by napisać IEquality comparer jak pokazano tutaj: http://msdn.microsoft.com/en-us/library/bb355408.aspx porównać swoje obiekty, a następnie wywołać Przecięcie metodę rozszerzenia:

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

hi Josh , próbowałem to: 'public bool równa się (ShowData x, ShowData y) { // Sprawdź, czy porównywane obiekty odnoszą się do tych samych danych. if (Object.ReferenceEquals (x, y)) zwraca wartość true; // Sprawdź, czy żaden z porównywanych obiektów nie jest pusty. if (Object.ReferenceEquals (x, null) || Object.ReferenceEquals (y, null)) return false; // Sprawdź, czy właściwości produktów są takie same. return x.HashData == y.HashData; } ' – user1112324

+0

ale nie jestem pewien jak to się kompiluje, gdy pojawia się błąd: iNumerumer nie zawiera definicji dla Intersect – user1112324

+0

@ user1112324 - Czy jesteś pewien, że umieściłeś instrukcję 'using' dla 'System.Linq' i ' System.Collections.Generic? Przecięcie jest z pewnością metodą rozszerzenia IEnumerable . –

1

Coś takiego może zadziałać (ostrzeżenie niesprawdzone):

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

Witam, próbowałem tego powyżej, ale otrzymuję inne wyniki, gdy przechodzę przez dwa zestawy i liczę dopasowania (recording.HashData == actual.HashData), a kiedy uruchamiam twoją metodę powyżej: IEnumerable zawiera = xyz (ShowData, recordingPoints); int return = zawiera.Liczyć(); – user1112324

+0

może to być spowodowane tym, że twoja metoda otrzymuje tylko unikalne wartości (tj. Jeśli jest już w zestawie powracającym, nie odczytała go). Potrzebuję go do odczytu, nawet jeśli już tam jest – user1112324

+0

Odpowiedź Josha prawdopodobnie będzie działać lepiej dla twoich celów (chociaż nie jestem pewien, czy Intersect zapewnia tylko Wyróżnione wyniki, czy też nie). –

Powiązane problemy