using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Diagnostics.Contracts; namespace APT.Infrastructure.Core { public static class QueryableOrderExtension { public static IQueryable SetQueryableOrder(this IQueryable query, string sort, string order, bool isThen = false) { if (string.IsNullOrEmpty(sort)) throw new Exception("必须指定排序字段!"); //PropertyInfo sortProperty = typeof(T).GetProperty(sort, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); //if (sortProperty == null) // throw new Exception("查询对象中不存在排序字段" + sort + "!"); ParameterExpression param = Expression.Parameter(typeof(T), "t"); Expression body = param; if (Nullable.GetUnderlyingType(body.Type) != null) body = Expression.Property(body, "Value"); body = GetPropertyLambdaExpression(body, sort); LambdaExpression keySelectorLambda = Expression.Lambda(body, param); if (string.IsNullOrEmpty(order)) order = "ASC"; string queryMethod = isThen ? order.ToUpper() == "DESC" ? "ThenByDescending" : "ThenBy" : order.ToUpper() == "DESC" ? "OrderByDescending" : "OrderBy"; query = query.Provider.CreateQuery(Expression.Call(typeof(Queryable), queryMethod, new Type[] { typeof(T), body.Type }, query.Expression, Expression.Quote(keySelectorLambda))); return query; } private static Expression GetPropertyLambdaExpression(Expression body, string fileName) { string[] propertyNames = fileName.Split('.'); Type type = body.Type; foreach (string propertyName in propertyNames) { PropertyInfo property = type.GetProperty(propertyName); //Contract.Assume(property != null); if (property == null) { throw new Exception($"类型{type.Name}不存在属性{propertyName}"); } type = property.PropertyType; body = Expression.MakeMemberAccess(body, property); } return body; } } }