.NET – Dynamische Abfragen mit LINQ erstellen

In den „guten“ alten Tagen, wo man noch mit SQL-Abfragen im Programmcode arbeitete war es leicht, dynamische Abfragen zu erstellen. Durch einfache Zeichenketten-Manipulationen konnten direkt SQL-Statements an die Datenbank gesendet werden. Die Zeichenketten liessen sich im Code zur Laufzeit zusammensetzen.

Mit der Einkehr von OR-Mappern, typisierten Entitäten und LINQ wurde zwar vieles vereinfacht und verbessert, doch fehlt für solche dynamischen Abfragen die Flexibilität. Auch wenn sich Expressions unter LINQ dynamisch zusammensetzen lassen – der Aufwand dafür ist extrem hoch und die Lernkurve dafür sehr steil.

Mittels der Bibliothek System.LINQ.Dynamic lassen sich Abfragen wieder im OLD-SQL-Style erstellen. Queries in der Form „SELECT Attr1, Attr2 FROM Entity WHERE Attr1=@0“ können nach der Installation der Biblothek in der LINQ Funktion Select() und Where() erstellt werden.

Wie diese Funktionen verwendet werden können, wird im folgenden Projekt-Beispiel kurz erläutert. Das Beispiel-Projekt basiert auf dem Entity Framework 6.0 mit Code First und als Datenbank-Provider wurde die In-Memory DB von Effort verwendet. Beide Libraries sind als NuGet-Pakete erhältlich.

Beispiel

Die Vorgaben des Beispiels sind:

  • Der Entitäts-Typ selbst ist dynamisch (Keine Verwendung von DbSet<Entity>)
  • Die SELECT-Felder sind parametrierbar
  • Die Where-Bedingung ist parametrierbar
  • Die Resultate werden inkl. Header-Zeile in einem Konsolen-Fenster wiedergegeben

1. Schritt „Erzeugen der Enitäten mittels Code-First“

Im Beispiel werden zwei Entitäten benötigt: Software und Hardware, beide abgeleitet von der Entität „Component“.

Entitites.cs

2. Schritt „DbContext erstellen“

Im DbContext werden die Entitäten „Software“ und „Hardware“ als DbSet hinzugefügt.

DynamicLINQDbContext.cs

3. Schritt „Programmlogik für die dynamische Abfrage erstellen“

Die dynamische Abfrage im nachfolgenden Code wird in den beiden Methoden Query() und PrintResult() erzeugt. Die restlichen Methoden dienen lediglich dem SetUp der Parameter.

Für die Parametrisierung wurde die Klasse „Field“ erzeugt. Durch sie wird zum einen festgelegt, welche Felder in der Query berücksichtigt werden sollen und ob sie in der Where-Bedingung verwendet werden sollen. Die nachstehende Parametrisierung erzeugt eine solche Abfrage:
SELECT Name, Description, Weight FROM Hardware WHERE Name=’Lenovo T530′ AND Weight > 4.0

 Program.cs

 

Tags: , , , , , ,

HINTERLASSE EINEN KOMMENTAR

lädt
×