Erstellen eines OrderBy-Lambda-Ausdrucks basierend auf der Eigenschaft der untergeordneten Entität

c# expression-trees lambda linq

Frage

Ich versuche, eine LINQ OrderBy Klausel unter Verwendung von Lambda-Ausdrücken mit einer Eingabe des Spaltennamens einer Entität als eine Zeichenfolge (in der "sortOn" Variablen unten) zu generieren.

Der folgende Code funktioniert gut für einen sortOn-Wert wie "Code", der das Lambda erzeugt

p => p.Code

Aber ich möchte auch nach einer Kind-Entität sortieren, wo das Lambda sein könnte

p => p.Category.Description

In diesem Fall möchte ich einfach sortOn = "Category.Description" setzen und den korrekten lamdba-Ausdruck generieren lassen.

Ist das möglich? Vorschläge für die beste Vorgehensweise wären willkommen.

Dieser Code funktioniert gut für den einfachen Fall:

var param = Expression.Parameter(typeof (Product), "p");

var sortExpression = Expression.Lambda<Func<Product, object>>(
    Expression.Property(param, sortOn), param);

if (sortAscending ?? true)
{
   products = products.OrderBy(sortExpression);
}
else
{
   products = products.OrderByDescending(sortExpression);
}

Der Anwendungsfall für dieses Problem ist das Anzeigen eines Datenrasters und das Sortieren der Daten, indem einfach der zu sortierende Spaltenname an den Server zurückgegeben wird. Ich möchte die Lösung generisch machen, habe aber vorerst damit begonnen, einen bestimmten Typ (Produkt im Beispiel) zu verwenden.

Akzeptierte Antwort

Dies erzeugt einen korrekten Lambda-Ausdruck:

var sortOn = "Category.Description";
var param = Expression.Parameter(typeof(Product), "p");
var parts = sortOn.Split('.');

Expression parent = param;

foreach (var part in parts)
{
    parent = Expression.Property(parent, part);
}

var sortExpression = Expression.Lambda<Func<Product, object>>(parent, param);

Beliebte Antwort

Sie können dazu die Dynamic LINQ Query Library verwenden. Angenommen, Sie haben eine IQueryable<T> des Product , können Sie IQueryable<T> tun:

IQueryable<Product> products = ...;

// Order by dynamically.
products = products.OrderBy("Category.Description");

Der Blogpost hat einen Link zur Bibliothek , und Sie müssen das Projekt selbst in Ihre Lösung einbauen / einfügen , aber es funktioniert sehr gut und das Parsing ist sehr robust. Es verhindert, dass Sie den Parsing-Code selbst schreiben müssen; selbst für etwas so einfaches, wenn die Anforderungen erweitern, die Bibliothek hat Sie abgedeckt, während eine selbstgewählte Lösung nicht.

Es hat auch eine Reihe anderer dynamischer Operatoren ( Select , Where , etc.), damit Sie andere dynamische Operationen ausführen können.

Es gibt keine Magie unter der Haube, es analysiert nur die Zeichenfolgen, an denen Sie es übergeben und erstellt dann die Lambda-Ausdrücke basierend auf den Analyseergebnissen.



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