解决 Linq 的 lambda 表达式排序不够灵活问题。

namespace Utility.Linq
{
    public static class QueryableExtend
    {
        /// <summary>
        /// 根据键按升序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "OrderBy");
            return source;
        }

        /// <summary>
        /// 根据键按降序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderByDescending<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "OrderByDescending");
            return source;
        }

        /// <summary>
        /// 根据某个键按降序对序列中的元素执行后续排序。
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="isDescending">是否倒序(可选,默认否)</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> ThenBy<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "ThenBy");
            return source;
        }

        /// <summary>
        /// 使用指定的比较器按降序对序列中的元素执行后续排序。
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="isDescending">是否倒序(可选,默认否)</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> ThenByDescending<TSource>(this IQueryable<TSource> source, string field)
        {
            source = source.OrderBy(field, "ThenByDescending");
            return source;
        }

        /// <summary>
        /// 根据键按升序对序列的元素排序
        /// </summary>
        /// <typeparam name="TSource">source 中的元素的类型</typeparam>
        /// <param name="source">一个要排序的值序列</param>
        /// <param name="field">排序字段</param>
        /// <param name="methodName">排序方法名</param>
        /// <returns>一个 System.Linq.IOrderedQueryable T,根据键对其元素排序。</returns>
        public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string field, string methodName)
        {
            if(source == null)
            {
                throw new ArgumentException("source");
            }
            if(field == null)
            {
                throw new ArgumentException("field");
            }
            if(methodName == null)
            {
                throw new ArgumentException("methodName");
            }
            Type entityType = typeof(TSource);
            ParameterExpression parameterExpression = Expression.Parameter(entityType, entityType.FullName);
            Expression propertyExpression = Expression.Property(parameterExpression, entityType.GetProperty(field));
            Expression expression = Expression.Lambda(propertyExpression, parameterExpression);
            PropertyInfo propertyInfo = entityType.GetProperty(field);
            Type propertyType = propertyInfo.PropertyType;
            Expression expr = Expression.Call(typeof(Queryable), methodName, new Type[] { entityType, propertyType }, source.Expression, expression);
            source = source.Provider.CreateQuery<TSource>(expr);
            return source;
        }
    }
}