zoukankan      html  css  js  c++  java
  • 实现动态排序

      1 /// <summary>
      2 /// 实现动态排序
      3 /// 来源博客园的一个大神,具体实现原理是利用实体和排序字段自动生成一个表达式
      4 /// 再利用IQuerable的方法实现
      5 /// 有一部分比较像微软的源码 ZhangQC 2016.10.20
      6 /// </summary>
      7 public static class DynamicOrder
      8 {
      9 #region Private 表达式树
     10 /// <summary>
     11 /// 构建表达式树 结果类似于 j=>j.Name
     12 /// </summary>ZhangQc 2016.10.20
     13 /// <typeparam name="TEntity"></typeparam>
     14 /// <param name="propertyName"></param>
     15 /// <param name="resultType"></param>
     16 /// <returns></returns>
     17 private static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType) where TEntity : class
     18 {
     19 PropertyInfo property;
     20 Expression propertyAccess;
     21 var parameter = Expression.Parameter(typeof(TEntity), "j");
     22 
     23 if (propertyName.Contains('.'))
     24 {
     25 String[] childProperties = propertyName.Split('.');
     26 property = typeof(TEntity).GetProperty(childProperties[0]);
     27 propertyAccess = Expression.MakeMemberAccess(parameter, property);
     28 for (int i = 1; i < childProperties.Length; i++)
     29 {
     30 property = property.PropertyType.GetProperty(childProperties[i]);
     31 propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
     32 }
     33 }
     34 else
     35 {
     36 property = typeof(TEntity).GetProperty(propertyName);
     37 propertyAccess = Expression.MakeMemberAccess(parameter, property);
     38 }
     39 
     40 resultType = property.PropertyType;
     41 
     42 return Expression.Lambda(propertyAccess, parameter);
     43 }
     44 
     45 /// <summary>
     46 /// 生成方法调用
     47 /// </summary>
     48 /// <typeparam name="TEntity"></typeparam>
     49 /// <param name="source"></param>
     50 /// <param name="methodName"></param>
     51 /// <param name="fieldName"></param>
     52 /// <returns></returns>
     53 private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName) where TEntity : class
     54 {
     55 Type type = typeof(TEntity);
     56 Type selectorResultType;
     57 LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
     58 MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
     59 new Type[] { type, selectorResultType },
     60 source.Expression, Expression.Quote(selector));
     61 return resultExp;
     62 }
     63 #endregion
     64 
     65 public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
     66 {
     67 MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderBy", fieldName);
     68 return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
     69 }
     70 
     71 public static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
     72 {
     73 MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderByDescending", fieldName);
     74 return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
     75 }
     76 
     77 public static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
     78 {
     79 MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenBy", fieldName);
     80 return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
     81 }
     82 
     83 public static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
     84 {
     85 MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenByDescending", fieldName);
     86 return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
     87 }
     88 public static IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
     89 {
     90 String[] orderFields = sortExpression.Split(',');
     91 IOrderedQueryable<TEntity> result = null;
     92 for (int currentFieldIndex = 0; currentFieldIndex < orderFields.Length; currentFieldIndex++)
     93 {
     94 String[] expressionPart = orderFields[currentFieldIndex].Trim().Split(' ');
     95 String sortField = expressionPart[0];
     96 Boolean sortDescending = (expressionPart.Length == 2) && (expressionPart[1].Equals("DESC", StringComparison.OrdinalIgnoreCase));
     97 if (sortDescending)
     98 {
     99 result = currentFieldIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
    100 }
    101 else
    102 {
    103 result = currentFieldIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
    104 }
    105 }
    106 return result;
    107 }
    108 
    109 
    110 //使用方法
    111 // var query = (from d in ((VinnoTech.Gaia2.DB.g2_dsource[])result)
    112 // join p in WebApiApplication.entities.g2_propnames
    113 // on d.dsource_item equals p.prop_name
    114 // orderby sidx
    115 // select new
    116 // {
    117 // d.dsource_id,
    118 // d.dsource_name,
    119 // dsource_item = p.prop_description,
    120 // d.dsource_description,
    121 // dsource_status = d.dsource_status == "1" ? "启用" : "禁用",
    122 // d.dsource_expiredday,
    123 // dsource_alarmhigh = (d.dsource_alarmhigh == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
    124 // dsource_alarmlow = (d.dsource_alarmlow == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
    125 // dsource_alarmdeltadata = (d.dsource_alarmdeltadata == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
    126 // dsource_alarmidle = (d.dsource_alarmidle == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
    127 // d.dsource_formula,
    128 // dsource_updatetime = d.dsource_updatetime.ToString("yyyy-MM-dd HH:mm:ss")
    129 // }).AsQueryable();
    130 
    131 //page = page <= query.Count() / rows + 1 ? page : 1;
    132 
    133 //query = query.OrderUsingSortExpression("dsource_name asc,dsource_item desc").Skip(rows * (page - 1)).Take(rows);
    134 }
  • 相关阅读:
    spring MVC配置详解
    sun.misc.BASE64Encoder找不到jar包的解决方法
    maven入门教程
    Mybatis与Hibernate的详细对比
    分享知识-快乐自己:Hibernate对象的三种状态
    分享知识-快乐自己:Hibernate框架常用API详解
    分享知识-快乐自己:Hibernate 中 get() 和 load()、sava、update、savaOrUpdate、merge,不同之处及执行原理?
    分享知识-快乐自己:Mybatis缓存机制
    分享知识-快乐自己:Hibernate中的 quert.list() 与 quert.iterate() 方法区别
    分享知识-快乐自己:SpringMvc整合遇到-前台传JSON参数,后台实体类对象接收
  • 原文地址:https://www.cnblogs.com/creater/p/6322040.html
Copyright © 2011-2022 走看看