using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace Win.Sfs.Shared.RepositoryBase { public static class QueryableExtension { public static IOrderedQueryable OrderBy(this IQueryable query, string propertyName) { return _OrderBy(query, propertyName, false); } public static IOrderedQueryable OrderByDescending(this IQueryable query, string propertyName) { return _OrderBy(query, propertyName, true); } private 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); var result = method?.Invoke(null, new object[] { query, memberProp }); return (IOrderedQueryable)result; } public static IOrderedQueryable OrderBy(this IQueryable query, Dictionary orderExpressions) { object tempQuery = query; var n = 0; foreach (var orderExpr in orderExpressions) { var propertyName = orderExpr.Key; var memberProp = typeof(T).GetProperty(propertyName); string methodName; if (n == 0) methodName = orderExpr.Value ? "OrderByInternal" : "OrderByDescendingInternal"; else methodName = orderExpr.Value ? "ThenByInternal" : "ThenByDescendingInternal"; var method = typeof(QueryableExtension).GetMethod(methodName)?.MakeGenericMethod(typeof(T), memberProp?.PropertyType); tempQuery = method?.Invoke(null, new object[] { tempQuery, memberProp }); n++; } return (IOrderedQueryable)tempQuery; } public static IOrderedQueryable OrderByInternal(IQueryable query, PropertyInfo memberProperty) {//public return query.OrderBy(_GetLambda(memberProperty)); } public static IOrderedQueryable OrderByDescendingInternal(IQueryable query, PropertyInfo memberProperty) {//public return query.OrderByDescending(_GetLambda(memberProperty)); } public static IOrderedQueryable ThenByInternal(IOrderedQueryable query, PropertyInfo memberProperty) {//public return query.ThenBy(_GetLambda(memberProperty)); } public static IOrderedQueryable ThenByDescendingInternal(IOrderedQueryable query, PropertyInfo memberProperty) {//public return query.ThenByDescending(_GetLambda(memberProperty)); } private static Expression> _GetLambda(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; } } }