IQueryable: Dynamisch eine OR-Filterung erstellen

c# expression-trees iqueryable linq linq-to-entities

Frage

Ich habe eine Reihe von Suchkriterien in dieser Form:

 member  |  value  |  operator
 --------+---------+---------
 height  |   10    |    >
 height  |    2    |    < 
 name    |  Carl   |   ==

Und ich möchte alle Objekte abfragen, die eines dieser Kriterien erfüllen.

Im Moment mache ich es durch:

  • Erstellen eines Ausdrucks für jedes der Kriterien
  • Verketten jedes Ausdrucks mit einem ODER-Ausdruck
  • Erstellen eines Lambda-Ausdrucks, der den verketteten Ausdruck enthält
  • Übergabe des Lambda-Ausdrucks an die Methode IQueryable <>. Where ()

Kennen Sie einen einfachen Weg, um eine IQueryable-Sammlung mit aufeinanderfolgenden OR-Werten dynamisch zu filtern?


BONUS Unsere Lösung:

Basierend auf IlyaBuiluk Lösung @ CodeProject

 member  |  value  |  operator
 --------+---------+---------
 height  |   10    |    >
 height  |    2    |    < 
 name    |  Carl   |   ==

Akzeptierte Antwort

In Bezug auf Leistung und Einfachheit der Implementierung ist dies ein besserer Ansatz als die Verwendung der Dynamic Query Library? Ich glaube, auf diese Weise haben Sie eine bessere Kontrolle über die SQL-Ausgabe Ihrer Ausdrucksbäume.

Von Raúl Roa


Beliebte Antwort

Wenn Sie eine feste Menge von Operatoren und eine feste Menge von Mitgliedern haben, dann können Sie dies fast schreiben, ohne sich direkt mit den Ausdrucksbäumen zu befassen. Die Idee besteht darin, einfache Lambda-Ausdrücke für verschiedene Code- Expression<Func<Entity, string>> zu erstellen (zB Expression<Func<Entity, string>> zum Lesen der Eigenschaft eines Members und ähnlich für Operatoren) und sie dann einfach zusammenzusetzen, um einen Ausdrucksbaum zu erstellen. Ich habe die Lösung hier beschrieben . Das einzige Problem ist, dass das Erstellen von Ausdrücken in C # nicht direkt unterstützt wird. Sie benötigen daher ein wenig Vorverarbeitung (siehe Abschnitt "Erweiterbare Hilfsprogramme").

Dann können Sie grundlegende Funktionen in einem Wörterbuch speichern und das richtige (oder eine Kombination davon) basierend auf dem auswählen, was der Benutzer auswählt. Zum Beispiel so etwas wie:

NorthwindDataContext db = new NorthwindDataContext();

// A query that tests whether a property 
// (specified by 'selector' matches a string value
var queryBuilder = Linq.Func
  ((Expression<Func<Customer, string>> selector, string val) =>
      from c in db.Customers.ToExpandable()
      where selector.Expand(c).IndexOf(val) != -1
      select c);

// Dictionary with supported members...
var dict = new Dictionary<string, Expression<Func<Customer, string>>> 
  { { "CompanyName", c => c.CompanyName },
    { "Country",     c => c.Country },
    { "ContactName", c => c.ContactName } };

// Ask user for a property name & value and Build the query
string field = Console.ReadLine();
string value = Console.ReadLine();
var q = queryBuilder(dict[field], value);

Der Artikel enthält auch ein Beispiel, in dem OR- oder AND-Bedingungen dynamisch zusammengestellt werden. Ich habe den Code für eine Weile nicht aktualisiert, also braucht er etwas Arbeit, aber ich glaube, dass LINQ KIT- Projekt auch eine Version dieser Idee enthält.




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum