Aktualnie pracuję nad aplikacją internetową w asp.net. W niektórych wywołaniach api należy porównać ListA z Listą B list, aby określić, czy ListA ma te same elementy dowolnej Listy na Liście B. Innymi słowy: jeśli lista ListA znajduje się na liście B.Jak skutecznie porównać listę?
Obie kolekcje są przeszukiwane za pomocą Linq kodu EF-Code-First db. ListB ma jedną pasującą listę lub żadną, nigdy więcej niż jedną. W najgorszym przypadku lista B zawiera miliony elementów, więc porównanie musi być skalowalne.
Zamiast robić zagnieżdżone pętle foreach, szukam czystego zapytania linq, które pozwoli db wykonać pracę. (Przed i rozważenia wielu indeks kolumny)
Aby zilustrować strukturę:
//In reality Lists are queried of EF
var ListA = new List<Element>();
var ListB = new List<List<Element>>();
List<Element> solution;
bool flag = false;
foreach (List e1 in ListB) {
foreach(Element e2 in ListA) {
if (e1.Any(e => e.id == e2.id)) flag = true;
else {
flag = false;
break;
}
}
if(flag) {
solution = e1;
break;
}
}
Aktualizacja struktury
Od jego bazy danych EF będę zapewnić odpowiednie struktury obiektu. Nie jestem pewien, czy mogę umieszczać prawdziwy kod, więc ten przykład jest nadal ogólny.
//List B
class Result {
...
public int Id;
public virtual ICollection<Curve> curves;
...
}
class Curve {
...
public int Id;
public virtual Result result;
public int resultId;
public virtual ICollection<Point> points;
...
}
public class Point{
...
public int Id;
...
}
Sterownik (dla wywołania api) chce podawać właściwy obiekt zakrzywiony. Aby zidentyfikować właściwy obiekt, dostarczany jest filtr (ListA) (który jest w rzeczywistości obiektem typu Curve). Teraz należy porównać filtr (ListA) z Listą krzywych w wyniku (lista B). Jedyny sposób na porównanie Krzywe to porównanie obu Punktów. (Tak więc porównujące listy) Krzywe mają około 1 - 50 punktów. Wynik może mieć około 500.000.000 krzywych.
Możliwe jest porównanie według Tożsamości Obiektu, ponieważ wszystkie Obiekty (nawet filtr) są ponownie sprawdzane w db.
Szukam sposobu na wdrożenie tego mechanizmu, a nie jak obejść tę sytuację. (Np za pomocą wielofunkcyjnego indeks kolumny (zmieniając tabelę))
(dla celów poglądowych):
class controller {
...
public Response serveRequest(Curve filter) {
foreach(Curve c in db.Result.curves) {
if(compare(filter.points , c.points)) return c;
}
}
}
Twój kod się nie skompiluje, prosze o wpisanie prawdziwego kodu. obs: jest to 'var' – Lucas
Musisz użyć sprzężenia wewnętrznego, ale bez znajomości struktury lepiej, trudno jej zasugerować. – Dexion
Powiązane, ale nie dupe z powodu problemów EF tutaj: http://stackoverflow.com/questions/9524681/linq-compare-two-lists –