C # Verwandeln magische Zeichenfolge in Lambda-Ausdruck

Ich habe eine Reihe von Erweiterungsmethoden, die die Verwendung magischer Zeichenfolgen in LINQ ermöglichenOrderBy() Methoden. Ich weiß, die erste Frage ist, warum, aber sie ist Teil eines generischen Repositorys und dient der Flexibilität, damit Zeichenfolgen von der Benutzeroberfläche gesendet und direkt verwendet werden können.

Ich habe es funktioniert, wenn Sie eine magische Zeichenfolge übergeben, die eine Eigenschaft der Hauptentität darstellt, die Sie abfragen, aber ich habe Probleme, es allgemeiner zu gestalten, damit es mehrere Ebenen tiefe magische Zeichenfolge verarbeiten kann. Zum Beispiel:

IQueryable<Contact> contacts = GetContacts();

contacts.OrderByProperty("Name"); // works great

// can't figure out how to handle this
contacts.OrderByProperty("ContactType.Name");

Hier ist der Code, den ich bisher habe:

public static class LinqHelpers
{
    private static readonly MethodInfo OrderByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderBy" && method.GetParameters().Length == 2);
    private static readonly MethodInfo OrderByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderByDescending" && method.GetParameters().Length == 2);
    private static readonly MethodInfo ThenByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "ThenBy" && method.GetParameters().Length == 2);
    private static readonly MethodInfo ThenByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "ThenByDescending" && method.GetParameters().Length == 2);

    public static IOrderedQueryable<TSource> ApplyOrdering<TSource>(IQueryable<TSource> source, string propertyName, MethodInfo orderingMethod)
    {
        var parameter = Expression.Parameter(typeof(TSource), "x");
        var orderByProperty = Expression.Property(parameter, propertyName);

        var lambda = Expression.Lambda(orderByProperty, new[] { parameter });

        var genericMethod = orderingMethod.MakeGenericMethod(new[] { typeof(TSource), orderByProperty.Type });

        return (IOrderedQueryable<TSource>)genericMethod.Invoke(null, new object[] { source, lambda });
    }

    public static IOrderedQueryable<TSource> OrderByProperty<TSource>(this IQueryable<TSource> source, string propertyName)
    {
        return ApplyOrdering(source, propertyName, OrderByMethod);
    }

    public static IOrderedQueryable<TSource> OrderByDescendingProperty<TSource>(this IQueryable<TSource> source, string propertyName)
    {
        return ApplyOrdering(source, propertyName, OrderByDescendingMethod);
    }

    public static IOrderedQueryable<TSource> ThenByProperty<TSource>(this IOrderedQueryable<TSource> source, string propertyName)
    {
        return ApplyOrdering(source, propertyName, ThenByMethod);
    }

    public static IOrderedQueryable<TSource> ThenByDescendingProperty<TSource>(this IOrderedQueryable<TSource> source, string propertyName)
    {
        return ApplyOrdering(source, propertyName, ThenByDescendingMethod);
    }
}

Ich bin mir ziemlich sicher, dass ich das aufteilen musspropertyName Verwenden Sie diese Teile, um einen komplizierteren Ausdruck zu erstellen, bei dem aMemberExpression und dann eine Immobilie, aber ich kämpfe. Jede Hilfe oder Hinweis in die richtige Richtung wäre dankbar.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage