Mehrere Suchparameter mit LINQ
Ich bin das schreiben, was ich glauben sollte ein relativ straight-forward-Windows Form app. Ich bin mit LINQ to SQL, aber ich habe es nie benutzt, bevor. Wir haben eine SQL Server-Datenbank, und ich bin die Schaffung eines front-end-Zugriff auf die Datenbank. Ich versuche, herauszufinden, den effizientesten Weg zu suchen, für mehrere (beliebig viele) Suche nach Parametern mit ihm.
In der windows-form, die ich erstellen ein Wörterbuch mit jeder Suche Schlüssel und dessen Wert zu suchen, und übergeben Sie in meine search () - Methode. Ich versuche einen Weg zu finden, um die Datenbank zu durchsuchen, die mit jeder dieser Schlüssel und die dazugehörigen Werte. Hier ist, was ich versuche zu tun:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
var query = dc.Products;
foreach (KeyValuePair<string, string> temp in searchParams)
{
query = query.Where(x => x.(temp.Key) == temp.Value);
}
return query;
}
Merke ich, dass syntaktisch x.(temp.Schlüssel) ist falsch, aber ich hoffe, das veranschaulicht, was ich versuche zu tun. Ich Frage mich, ob es einen anderen Weg zu gehen über das, was ich versuche zu tun, ohne zu tun, eine riesige switch-Anweisung (if/else if-Struktur).
BEARBEITEN
So, ich überarbeitete es ein wenig, aber ich bin immer noch Probleme mit ihm. Hier ist, was ich derzeit habe:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
string sQuery = "";
foreach (KeyValuePair<string, string> temp in searchParams)
{
sQuery += temp.Key + "=" + temp.Value + " AND ";
}
var query = dc.Products.Where(sQuery);
return query;
}
Entsprechend der LINQ Dynamic Query Library-Artikel, das sollte OK sein. Hier ist der Fehler, die ich immer bin:
Den Typ der Argumente für die Methode 'System.Linq -.Queryable.Wo(System.Linq -.IQueryable, System.Linq -.Ausdrücke.Ausdruck>)' kann nicht abgeleitet werden aus der Nutzung. Versuchen Sie, den Typ der Argumente explizit.
- Gibt es einen Grund, dass die Such-parameter der Methode muss ein Wörterbuch eher als eine Func - <Produkt -, bool> ???
- Nicht ganz sicher, was du damit meinst... könntest du das bitte klären?
- Jeden Schlüssel im dictionary enthält die Parameter für die Suche (und jedem Parameter Wert zu suchen).
- Gemäß Ihrer dynamischen Abfrage-generator Beispiel, ich habe einen edit in Bezug auf das "UND" am Ende unten, das wird sich hoffentlich lösen es für Sie.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ein Beispiel das funktioniert (habe es gerade getestet), mit der Dynamische LINQ-Abfrage Bibliothek.
Und, um es absolut klar, dass dieser code tatsächlich funktioniert hier ist die tatsächlichen generierten SQL:
Wenn das Wörterbuch ist nicht erforderlich, für einige Grund, würde ich die Suche-Methode wie folgt:
Dann würden Sie die Methode verwenden, etwa so:
Gibt es irgendein Grund, dass Sie nicht tun können?
[Edit: Hinzugefügt AsQueryable()]
[Edit: für Dynamische Abfragen mit strings]
Schauen Sie hier und sehen, ob das hilft. Ich habe Sie noch nicht benutzt, aber sieht aus wie es ist, was du suchst:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Persönlich würde ich es bevorzugen in der Regel die Typ-sicheren Ausdruck> Ansatz, da dies wird Ihnen compile-Zeit-Fehler...aber wenn strings benötigt werden, sieht dann aus wie der beste Weg, es zu tun.
Basierend auf den obigen link, sieht aus wie Sie sollten in der Lage sein zu tun:
[Edit: String-Gebäude Beispiel]
So, eines der Probleme ist, dass Sie Ihre sql-Abfrage wird zu Ende gehen mit ein UND am Ende der Zeichenkette, aber keine Bedingung nach es...also, vielleicht versuchen Sie dieses... - syntax vielleicht etwas ab, aber sollte richtig sein:
Diese werden nur mit "UND" über die Bedingungen nach dem ersten. Hoffe, es hilft...
FYI - Es ist off-topic, aber 'warum' ich verwendet StringBuilder ist, dass die string-Verkettung, die Art und Weise, die Sie hatten, würde das Ergebnis in der string zerstört wird und eine neue Zeichenfolge erstellt werden die in-memory-4 mal pro loop...so geändert, um ein StringBuilder-da schaffen, einen Puffer, der gefüllt werden kann und nur geändert werden, wenn notwendig.
IEnumerable
, nichtIQueryable
, so dass der code nicht kompiliert. Des weiteren Zeilen aus der Datenbank gefiltert werden, die in C# - code nicht in der Datenbank-Schicht. Es wird langsamer und benötigt mehr Speicher.Anstelle von Wörterbuch Sie können diese Methode verwenden:
Können Sie es verwenden, wie diese:
Du auch nicht begrenzt werden, um string-Eigenschaften.
haben u versuchen Sie, setzen Sie einfache Anführungszeichen für den string?
basierend auf Ihren foreach-Schleife, es werden zusätzliche 'UND' am Ende der Abfrage
versuchen, diese stattdessen
wenn Sie bereit sind, um ein Wörterbuch zu erstellen von suchbaren Begriffe, als die, die ich verwendet habe, etwas in der Nähe der Ansatz unten. Ich habe angepasst, was zu tun ich mehr eng fit in, wie Sie waren, Dinge zu tun, habe ich auch geändert die Namen der Tabellen, um zu passen ein datacontext-Objekt-Modell, das ich zur Verfügung habe, um mich.
Die Idee ist, erstellen Sie ein keyed Liste der Begriffe, die Abfrage unterstützt die Suche, nach. Dann fügen Sie Funktionen, die einen Ausdruck übermittelt werden können, die in der where-Klausel der Abfrage.
Sollten Sie natürlich fügen Sie einige Fehlerbehandlung für ungültige keys etc.