使用 Linq.Expressions.Expression 排序
Posted
技术标签:
【中文标题】使用 Linq.Expressions.Expression 排序【英文标题】:Sort using Linq.Expressions.Expression 【发布时间】:2012-08-30 07:54:01 【问题描述】:我编写的这段代码按sortColumn
列对IQueryable<T>
进行排序。我想扩展它,以便将列 BirthDate
的值等于 DateTime.Today
的条目放在排序的首位,但我就是找不到或想不出如何完成这项工作。
public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string sortColumn, bool asc)
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, sortColumn);
var exp = Expression.Lambda(prop, param);
string method = asc ? "OrderBy" : "OrderByDescending";
Type[] types = new[] q.ElementType, exp.Body.Type ;
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
【问题讨论】:
见:***.com/questions/298725/multiple-order-by-in-linq 这可行,但我无法使用参数“sortColumn”对所需的任何列进行排序,除非我使用大量 if()s。 首先,您不应该在这里返回IOrderedQueryable
吗?其次,您不能创建另一个扩展 IOrderedQueryable
而不是使用 ThenBy
和 ThenByDescending
作为 Queryable
方法的 IQueryable
的副本吗?
【参考方案1】:
见Handle GridView.OnSorting() and create sorting expression dynamically using LINQ
public static class SortExpressionBuilder<T>
private static IDictionary<SortDirection, ISortExpression> directions = new Dictionary<SortDirection, ISortExpression>
SortDirection.Ascending, new OrderByAscendingSortExpression() ,
SortDirection.Descending, new OrderByDescendingSortExpression()
;
interface ISortExpression
Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression();
class OrderByAscendingSortExpression : ISortExpression
public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
return (c, f) => c.OrderBy(f);
class OrderByDescendingSortExpression : ISortExpression
public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
return (c, f) => c.OrderByDescending(f);
public static Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> CreateExpression(SortDirection direction)
return directions[direction].GetExpression();
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> collection, string columnName, SortDirection direction)
ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x
Expression property = Expression.Property(param, columnName); // x.ColumnName
Func<T, object> func = Expression.Lambda<Func<T, object>>( // x => x.ColumnName
Expression.Convert(Expression.Property(param, columnName),
typeof(object)), param
).Compile();
Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> expression = SortExpressionBuilder<T>.CreateExpression(direction);
IEnumerable<T> sorted = expression(collection, func);
return sorted;
以及底部的链接:
Sorting a list using Lambda/Linq to objects GridView sorting: SortDirection always Ascending【讨论】:
【参考方案2】:您可以尝试对类似于以下表达式的内容进行排序:
.OrderBy(x => BirthDate == DateTime.Now.Date ? 0 : 1).ThenBy(sortColumn);
【讨论】:
以上是关于使用 Linq.Expressions.Expression 排序的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)