2010-07-05 5 views
24

Wenn ich eine Liste von Objekten gegen eine bestimmte ID filtern mag, kann ich dies tun:Lambda-Ausdruck in der Liste ist für existiert

list.Where(r => r.Id == idToCompare); 

Was, wenn statt einer einzelnen idToCompare, ich habe eine Liste von Ids gegen vergleichen?

Wie lautet die Syntax für den Vergleich mit einer vordefinierten Liste? Etwas wie:

int[] listofIds = GetListofIds(); 

list.Where(r => r.Id "in listofIds"); 

Antwort

46

Wenn listOfIds ist eine Liste, dies funktionieren wird, aber, List.Contains() ist eine lineare Suche, so ist dies nicht sehr effizient.

Sie sollten besser die IDs speichern, die Sie in einem Container suchen möchten, der für die Suche geeignet ist, wie Set.

List<int> listOfIds = new List(GetListOfIds()); 
lists.Where(r=>listOfIds.Contains(r.Id)); 
4

Sie die() Erweiterungsmethode Enthält verwenden:

list.Where(r => listofIds.Contains(r.Id)) 
19
var query = list.Where(r => listofIds.Any(id => id == r.Id)); 

Ein weiterer Ansatz, nützlich, wenn die listOfIds Array ist groß:

HashSet<int> hash = new HashSet<int>(listofIds); 
var query = list.Where(r => hash.Contains(r.Id)); 
+2

Verwendung mit Rahmen Entity (und möglicherweise LINQ-To-SQL), wird dies übersetzt tatsächlich in „SELECT * FROM Tabelle mit ID in (1,2,3,4) ", was zu einer einzigen Reise zum Server führt. –

+0

@IgorZevaka - wenn es die Datenbank mit EF abfragen wird, werde ich lieber SortedSet verwenden (was eine Art Superset von HashSet ist). Es ist auch einzigartig, wie HashSet, aber auch Sorted. Ich werde dann meine Db-Spalte indexieren, auf der ich die Where-Klausel ausführen werde. Das wird in großen Datenmengen wesentlich schneller sein. – sandiejat

0

ich das aussehen würde Bediener beitreten:

from r in list join i in listofIds on r.Id equals i select r 

Ich bin nicht sicher, wie dies über die Contains-Methoden optimiert werden würde, aber zumindest gibt es dem Compiler eine bessere Vorstellung von dem, was Sie versuchen zu tun. Es ist auch semisch näher an dem, was Sie erreichen möchten.

Edit: Erweiterung Methode Syntax auf Vollständigkeit (jetzt, dass ich es gedacht habe out):

var results = listofIds.Join(list, i => i, r => r.Id, (i, r) => r); 
+1

Ich war dabei, dieselbe Antwort zu posten (obwohl ich die Syntax der Erweiterungsmethode verwende, aber das ist nur eine persönliche Vorliebe). Und ja, 'Join' ist mehr optimiert als' Contains', da es eine In-Memory-Hash-Tabelle der Schlüssel auf beiden Seiten erstellt, anstatt eine sequentielle Suche in 'listOfIds' für jedes Mitglied von' list' durchzuführen. –

+0

@Anthony Pegram: Danke, ich habe es gerade herausgefunden und meinen Kommentar gelöscht, sorry. Als Referenz sagte ich, ich konnte die Syntax nicht herausfinden und bat um Hilfe – TheEvilPenguin

Verwandte Themen