2010-11-18 6 views
2

Ich habe eine Datenbanktabelle, die "Befehle" und "states" enthält. Jeder Befehl kann mehrere Zustände haben, und der Benutzer kann dies bei der Suche konfigurieren. Zum Beispiel könnte der Befehl "Ausführen" sein und er könnte zwei Zustände haben: "Schnell" und "Langsam".Erweiterte Datenbanksuche mit linq-to-sql help

Ich möchte meine Tabelle nach allen Befehlen suchen, die "Run" mit "Fast" oder "Slow" genannt werden. Das ist ziemlich einfach zu tun:

var results = from t in table 
       where t.Command == "Run" && 
       (t.State == "Fast" || t.State == "Slow") 
       return t; 

jedoch der Benutzer auch Befehl „Walk“ mit Zustand „Fast“, und so die Abfrage würde so aussehen suchen könnte:

var results = from t in table 
        where (t.Command == "Run" && 
         (t.State == "Fast" || t.State == "Slow")) || 
        (t.Command == "Walk" && 
        t.State == "Fast") 
        return t; 

Es gibt ein Potenzial für So viele Suchen wie diese, und ich frage mich, wie man sie in einer Art Schleife kombinieren kann.

Ich kann das nicht tun:

foreach(var command in commands) 
{ 
    foreach(var state in command.states) 
    { 
     results = from t in table 
        where t.Command == command.Command && 
        t.State == state; 
    } 
} 

weil, sobald es für „Run“ sucht, „Walk“ aus Ergebnissen gelassen werden würde, so zu fragen für „Weg“ in keinen Ergebnissen alle zur Folge hätte.

Kennt jemand eine gute Möglichkeit, dies zu tun?

Antwort

7

Verwenden Joe Albahari der PredicateBuilder ein Prädikat zu bauen:

var predicate = PredicateBuilder.False<Entry>(); 
foreach(var command in commands) 
{ 
    foreach(var state in command.states) 
    { 
     predicate = predicate.Or(p => p.Command == command.Command && p.State == state); 
    } 
} 
var query = table.Where(predicate); 

Oder eine LINQ-schwere Ausführung:

var commandStates = from c in commands 
        from s in c.states 
        select new {c.Command, State = s}; 
var predicate = commandStates.Aggregate(
    PredicateBuilder.False<Entry>(), 
    (pred, e) => pred.Or(p => p.Command == e.Command && p.State == e.state)); 
var query = table.Where(predicate); 
+0

+1 Snap - fast :) –

+0

dies tatsächlich sehr aktuell ist (das Prädikat builder) als ich humpelte von spät aggregieren where clauses - nice find. Wie ist dein Erfolg damit verbunden? –

+0

@jim: Ich hatte eigentlich noch keine Notwendigkeit dafür. Das meiste von dem, was wir tun, ist entweder einfach genug, um es nicht zu brauchen, oder fortgeschritten genug, dass ich den ganzen Ausdrucksbaum trotzdem von Hand bauen muss. Wenn Sie PredicateBuilder verwenden, sollten Sie sich LinqKit im Allgemeinen ansehen. Es hat einige praktische Funktionen zum Aufrufen von Prädikaten und Dingen. – StriplingWarrior