1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 using System.Reflection; 6 7 static class LinqExtensions 8 { 9 private static PropertyInfo GetPropertyInfo(Type objType, string name) 10 { 11 var properties = objType.GetProperties(); 12 var matchedProperty = properties.FirstOrDefault(p => p.Name == name); 13 if (matchedProperty == null) 14 throw new ArgumentException("name"); 15 16 return matchedProperty; 17 } 18 private static LambdaExpression GetOrderExpression(Type objType, PropertyInfo pi) 19 { 20 var paramExpr = Expression.Parameter(objType); 21 var propAccess = Expression.PropertyOrField(paramExpr, pi.Name); 22 var expr = Expression.Lambda(propAccess, paramExpr); 23 return expr; 24 } 25 26 public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> query, string name) 27 { 28 var propInfo = GetPropertyInfo(typeof(T), name); 29 var expr = GetOrderExpression(typeof(T), propInfo); 30 31 var method = typeof(Enumerable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2); 32 var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); 33 return (IEnumerable<T>)genericMethod.Invoke(null, new object[] { query, expr.Compile() }); 34 } 35 36 public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string name) 37 { 38 var propInfo = GetPropertyInfo(typeof(T), name); 39 var expr = GetOrderExpression(typeof(T), propInfo); 40 41 var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2); 42 var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); 43 return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); 44 } 45 46 public static IEnumerable<T> OrderByDescending<T>(this IEnumerable<T> query, string name) 47 { 48 var propInfo = GetPropertyInfo(typeof(T), name); 49 var expr = GetOrderExpression(typeof(T), propInfo); 50 51 var method = typeof(Enumerable).GetMethods().FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2); 52 var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); 53 return (IEnumerable<T>)genericMethod.Invoke(null, new object[] { query, expr.Compile() }); 54 } 55 56 public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string name) 57 { 58 var propInfo = GetPropertyInfo(typeof(T), name); 59 var expr = GetOrderExpression(typeof(T), propInfo); 60 61 var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2); 62 var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); 63 return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); 64 } 65 }
用法:
var r = new List<temp> { new temp { a = 5 }, new temp { a = 1 }, new temp { a = 15 } }.OrderBy("a");
来源:https://stackoverflow.com/questions/32061770/call-orderby-with-a-field-name-as-a-string