使用linq的OrderBy,如果明确知道是哪个字段,当然很容易:
IQueryableuserQuery = ...; userQuery.OrderBy(u => u.Code)
但假如我们想写一个通用方法,预先并不知道要用哪个字段排序呢?
在网上寻寻觅觅,有许多国内的博客互相抄袭,信誓旦旦,但其实那些代码都运行不了。
还是老外的好使:
我拿来修改了一下,可以用。主要思想是扩展Queryable。但里面的东西有许多我都看不懂。
public static class QueryableExtension { public static IOrderedQueryableOrderBy (this IQueryable query, string propertyName) { return _OrderBy (query, propertyName, false); } public static IOrderedQueryable OrderByDescending (this IQueryable query, string propertyName) { return _OrderBy (query, propertyName, true); } static IOrderedQueryable _OrderBy (IQueryable query, string propertyName,bool isDesc) { string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal"; var memberProp = typeof(T).GetProperty(propertyName); var method = typeof(QueryableExtension).GetMethod(methodname) .MakeGenericMethod(typeof(T), memberProp.PropertyType); return (IOrderedQueryable )method.Invoke(null, new object[] { query, memberProp }); } public static IOrderedQueryable OrderByInternal (IQueryable query, PropertyInfo memberProperty) { //public return query.OrderBy(_GetLamba (memberProperty)); } public static IOrderedQueryable OrderByDescendingInternal (IQueryable query, PropertyInfo memberProperty) { //public return query.OrderByDescending(_GetLamba (memberProperty)); } static Expression > _GetLamba (PropertyInfo memberProperty) { if (memberProperty.PropertyType != typeof(TProp)) throw new Exception(); var thisArg = Expression.Parameter(typeof(T)); var lamba = Expression.Lambda >(Expression.Property(thisArg, memberProperty), thisArg); return lamba; } }
调用:
IQueryableuserQuery = ...;//正序userQuery = userQuery.OrderBy("Code");//降序userQuery = userQuery.OrderByDescending("Code");