Sortieren unter Verwendung des Eigenschaftsnamens als Zeichenfolge

asp.net asp.net-core c# entity-framework-core linq

Frage

Ich möchte, dass meine Web-API ihre Ausgabe nach einem String-Parameter wie diesem sortiert:

http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true .

Da ich in meiner API auch Unterstützung für Paginierung (mit skip und take ) habe, möchte ich, dass der Parameter orderBy und descending direkt auf die SQL-Abfrage angewendet wird, sodass das korrekte Ergebnis von der Datenbank kommt.

Wenn Sie dies tun, kann es jedoch sehr schwierig werden, den Code zu verwalten, wenn Sie versuchen, die Parameter für orderBy mit den tatsächlichen Eigenschaften der Klassen, die ich sortieren möchte, zu vergleichen, indem Sie nur Zeichenfolgenvergleiche verwenden.

Ich habe eine Lösung gefunden, die mit LINQ zu Entities und somit auch mit dem neuen EF7 funktionieren soll, aber wenn ich versuche, diesen Code mit der neuen Core CLR zu kompilieren, bekomme ich folgende Meldung:

Fehler CS1503 Argument 2: Konvertierung von 'System.Linq.Expressions.Expression>' zu 'String' nicht möglich

Der Code der OrderBy<T> Lösung ist die OrderBy<T> -Methode:

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return source.OrderBy(ToLambda<T>(propertyName));
}

Es scheint, dass die neue Core CLR diesen Versuch nicht unterstützt. Gibt es eine andere Möglichkeit, die Lösung mit der neuen CLR zu arbeiten? Wenn nein, welche anderen Alternativen muss ich aktivieren EF7 Sortierung verwenden , ohne in unzähligen resultierenden if oder switch Anweisungen , um die Eingabezeichenfolgen auf den Eigenschaftsnamen zu vergleichen?

Akzeptierte Antwort

Die Lösung von Ihrem Link verwendet ein "Expression.Convert", das die meiste Zeit nicht mit LINQ to Entities funktioniert.

Hier ist eine funktionierende Erweiterungsmethode:

public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
    // LAMBDA: x => x.[PropertyName]
    var parameter = Expression.Parameter(typeof(TSource), "x");
    Expression property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    // REFLECTION: source.OrderBy(x => x.Property)
    var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
    var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource), property.Type);
    var result = orderByGeneric.Invoke(null, new object[] { source, lambda });

    return (IOrderedQueryable<TSource>)result;
}

Disclaimer : Ich bin der Besitzer des Projekts EF + auf GitHub.

Sie können andere Methoden zum Sortieren nach Eigenschaftsnamen in meinem Repository finden: GitHub

  • OrderByDescending
  • Dann
  • DannByDescending
  • AddOrAppendOrderBy
  • AddOrAppendOrderByDescending

EDIT : Beantworten Sie die Unterfrage

Ist es möglich, nach Navigationseigenschaften zu sortieren, die so etwas verwenden, zB ein Eigenschaftsname "NavigationProperty.PropertyName"

Ja, Sie können die Zeichenfolge und die Schleife entweder aufteilen, um den Ausdruck mit dem Eigenschaftenpfad zu erstellen, oder einen echten Ausdruckauswerter verwenden.

Haftungsausschluss : Ich bin der Inhaber des Projekts EvalExpressions.NET

Mit dieser Bibliothek können Sie alle LINQ-Methoden dynamisch ausführen.

Siehe: LINQ Dynamisch

var result = list.OrderByDynamic(x => "NavigationProperty.PropertyName");


Related

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