具有动态Order By的LINQ查询

Pit*_*ger 9 .net c# linq sql-order-by

我有一个查询,我需要根据查询字符串参数进行ordeby.例如,如果sortby参数是价格,Query需要随价格变化.如果其评级比更改查询按评级排序.

我知道PredicateBuilder可以做And和OR的东西,但我如何进行动态ordeby linq查询.

lon*_*ero 21

如果你确切知道哪些是可用于订购的可能参数,那么Jon的答案是最好的.但是,如果您有未知数量的参数,则可以动态构建表达式.例如:

class Program
{
    static void Main(string[] args)
    {
        var people = new[]{
            new Person { Name = "David", Age = 40 },
            new Person { Name = "Maria", Age = 12 },
            new Person { Name = "Lucas", Age = 45 }
        }.AsQueryable();

        foreach (var p in people.OrderBy("Age"))
        {
            Console.Write(p.Name);
        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

static class IQueryableExtensions
{
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> items, string propertyName)
    {
        var typeOfT = typeof(T);
        var parameter = Expression.Parameter(typeOfT, "parameter");
        var propertyType = typeOfT.GetProperty(propertyName).PropertyType;
        var propertyAccess = Expression.PropertyOrField(parameter, propertyName);
        var orderExpression = Expression.Lambda(propertyAccess, parameter);

        var expression = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { typeOfT, propertyType }, items.Expression, Expression.Quote(orderExpression));
        return items.Provider.CreateQuery<T>(expression);
    }        
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 15

好吧,你可以使用switch语句或类似的东西:

IQueryable<Foo> query = ...;

switch (orderByParameter)
{
    case "price":
        query = query.OrderBy(x => x.Price);
        break;
    case "rating":
        query = query.OrderBy(x => x.Rating);
        break;
    // etc
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用反射来完成它,但假设您有可用的有限数量的字段,这很可能是最简单的方法.