Lambda 表达式中 动态解析OrderbyLinQ语句的实现
添加方法:
public static IOrderedQueryable<T> OrderBy<T>(this IEnumerable<T> source, string property,string orderType) { if(orderType.ToLower()=="desc") return ApplyOrder<T>(source, property, "OrderByDescending"); return ApplyOrder<T>(source, property, "OrderBy"); } public static IOrderedQueryable<T> OrderBy<T>(this IEnumerable<T> source, string property) { return ApplyOrder<T>(source, property, "OrderBy"); } public static IOrderedQueryable<T> OrderByDescending<T>(this IEnumerable<T> source, string property) { return ApplyOrder<T>(source, property, "OrderByDescending"); } public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property) { return ApplyOrder<T>(source, property, "ThenBy"); } public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property) { return ApplyOrder<T>(source, property, "ThenByDescending"); } static IOrderedQueryable<T> ApplyOrder<T>(IEnumerable<T> source, string property, string methodName) { string[] props = property.Split('.'); Type type = typeof(T); ParameterExpression arg = Expression.Parameter(type, property); Expression expr = arg; //foreach (string prop in props) //{ // // use reflection (not ComponentModel) to mirror LINQ // PropertyInfo pi = type.GetProperty(prop); // expr = Expression.Property(expr, pi); // type = pi.PropertyType; //} const BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance; PropertyInfo pi = type.GetProperty(property,flag); expr = Expression.Property(expr, pi); type = pi.PropertyType; // Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type); LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); object result = typeof(Queryable).GetMethods().Single( method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T), type) .Invoke(null, new object[] { source, lambda }); return (IOrderedQueryable<T>)result; }
调用语句:
var iqlist = _wMSensorTypeRepository.GetAll() //查询 .WhereIf(input.SearchValue != null && !string.IsNullOrEmpty(input.SearchValue), m => m.SensorTypeCode.Contains(input.SearchValue) || m.SensorTypeName.Contains(input.SearchValue) || m.Remarks.Contains(input.SearchValue)) //排序 .OrderBy(input.SortColName, input.SortType) //页码 .Skip(input.PageSize*(input.PageNumber - 1)).Take(input.PageSize).ToList(); var list = Mapper.Map<IList<Entities.WMSensorType>, IList<WMSensorTypeDto>>(iqlist).ToList();
交互对象:
/// <summary> /// 此类定义了分页查询的输入,包含搜索,排序 /// </summary> public class PageInput { public PageInput() { PageNumber = 1; PageSize = 20; SortColName = ""; SortType = "asc"; SearchValue = ""; } public int PageNumber { get; set; } /// <summary> /// 每页记录数 /// </summary> public int PageSize { get; set; } /// <summary> /// 排序列名称 /// </summary> public string SortColName { get; set; } /// <summary> /// 排序类型 desc asc /// </summary> public string SortType { get; set; } /// <summary> /// 检索字符 /// </summary> public string SearchValue { get; set; } } /// <summary> /// 页面输出结果 /// </summary> /// <typeparam name="T"></typeparam> public class PageOutput<T> : IOutputDto { public int PageNumber { get; set; } /// <summary> /// 总页数 /// </summary> public int TotalPages { get; set; } /// <summary> /// 每页记录数 /// </summary> public int PageSize { get; set; } public List<T> DataItems { get; set; } }