using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Ropin.Inspection.Repository { internal static class LinqExtensions { private static PropertyInfo GetPropertyInfo(Type objType, string name) { var properties = objType.GetProperties(); var matchedProperty = properties.FirstOrDefault(p => p.Name == name); if (matchedProperty == null) { throw new ArgumentException("name"); } return matchedProperty; } private static LambdaExpression GetOrderExpression(Type objType, PropertyInfo pi) { var paramExpr = Expression.Parameter(objType); var propAccess = Expression.PropertyOrField(paramExpr, pi.Name); var expr = Expression.Lambda(propAccess, paramExpr); return expr; } /// /// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime" /// /// /// /// /// public static IEnumerable OrderByBatch(this IEnumerable query, string name) { var index = 0; var a = name.Split(','); foreach (var item in a) { var m = index++ > 0 ? "ThenBy" : "OrderBy"; if (item.StartsWith("-")) { m += "Descending"; name = item.Substring(1); } else { name = item; } name = name.Trim(); var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Enumerable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); query = (IEnumerable)genericMethod.Invoke(null, new object[] { query, expr.Compile() }); } return query; } /// /// 多个OrderBy用逗号隔开,属性前面带-号表示反序排序,exp:"name,-createtime" /// /// /// /// /// public static IQueryable OrderByBatch(this IQueryable query, string name) { var index = 0; var a = name.Split(','); foreach (var item in a) { var m = index++ > 0 ? "ThenBy" : "OrderBy"; if (item.StartsWith("-")) { m += "Descending"; name = item.Substring(1); } else { name = item; } name = name.Trim(); var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); query = (IQueryable)genericMethod.Invoke(null, new object[] { query, expr }); } return query; } /// /// 正序排序单个 /// /// /// /// /// public static IQueryable OrderBy(this IQueryable query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr }); } /// /// 正序排序单个(非首个) /// /// /// /// /// public static IQueryable ThenBy(this IQueryable query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "ThenBy" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr }); } /// /// 反序排序单个 /// /// /// /// /// public static IQueryable OrderByDescending(this IQueryable query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var metMethods = typeof(Queryable).GetMethods(); var method = metMethods.FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr }); } /// /// 反序排序单个(非首个) /// /// /// /// /// public static IQueryable ThenByDescending(this IQueryable query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var metMethods = typeof(Queryable).GetMethods(); var method = metMethods.FirstOrDefault(m => m.Name == "ThenByDescending" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable)genericMethod.Invoke(null, new object[] { query, expr }); } } }