具有动态Order By的LINQ查询

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

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

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

IQueryable query = ...; switch (orderByParameter) { case "price": query = query.OrderBy(x => x.Price); break; case "rating": query = query.OrderBy(x => x.Rating); break; // etc } 

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

如果您确切知道哪些是可用于订购的可能参数,那么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 OrderBy(this IQueryable 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(expression); } } 

扩展@lontivero答案。

如果您想要对升序和降序的多个项目进行动态排序,您可以执行类似下面的操作。 添加OrderByDescending,ThenBy,ThenByDescending方法

 static class IQueryableExtensions { public static IQueryable OrderBy(this IQueryable 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(expression); } public static IQueryable OrderByDescending(this IQueryable 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), "OrderByDescending", new Type[] { typeOfT, propertyType }, items.Expression, Expression.Quote(orderExpression)); return items.Provider.CreateQuery(expression); } public static IQueryable ThenBy(this IQueryable 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), "ThenBy", new Type[] { typeOfT, propertyType }, items.Expression, Expression.Quote(orderExpression)); return items.Provider.CreateQuery(expression); } public static IQueryable ThenByDescending(this IQueryable 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), "ThenByDescending", new Type[] { typeOfT, propertyType }, items.Expression, Expression.Quote(orderExpression)); return items.Provider.CreateQuery(expression); } }