实现动态排序

  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 }

 

转载于:https://www.cnblogs.com/creater/p/6322040.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MybatisPlus中提供了一个OrderByWrapper类来实现动态排序。 首先,需要导入MybatisPlus的相关依赖,然后使用OrderByWrapper类中的orderBy()方法来进行动态排序。 在代码中使用方法如下: OrderByWrapper<User> orderByWrapper = new OrderByWrapper<>(); orderByWrapper.orderBy("age", false); 然后将orderByWrapper作为参数传入到查询方法中即可。 例如: List<User> users = userMapper.selectList(orderByWrapper); 这样就可以实现根据age字段降序排序了 多字段可以使用 orderBy(String column, boolean isAsc) 多次调用,实现多字段的排序。 ### 回答2: MyBatis Plus是一个基于MyBatis的增强工具,它简化了MyBatis的开发流程并提供了更多的便捷功能。在MyBatis Plus中,动态排序可以通过使用Lambda表达式来实现。 首先,我们需要在实体类中定义排序字段的属性。例如,我们在实体类中定义了一个名为"age"的属性,用于按年龄排序。 然后,在查询中使用QueryWrapper类构建查询条件,并调用orderBy方法进行动态排序。例如,我们可以通过下面的代码实现按年龄倒序排序: ``` QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc(User::getAge); List<User> userList = userMapper.selectList(queryWrapper); ``` 这段代码中,我们通过QueryWrapper的orderByDesc方法指定了按照年龄倒序排序。User::getAge是Lambda表达式,用于指定排序的属性。 除了orderByDesc方法,MyBatis Plus还提供了其他常用的排序方法,如orderByAsc、orderBy、orderByDesc、orderByAsc和orderByDesc等,可以根据实际需求选择使用。 在MyBatis Plus中,动态排序还可以与其他查询条件结合使用。例如,我们可以同时按照年龄倒序排序和根据性别查询用户: ``` QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc(User::getAge).eq(User::getGender, "male"); List<User> userList = userMapper.selectList(queryWrapper); ``` 这段代码中,我们在orderByDesc方法后面添加了eq方法,用于指定查询条件。这样就可以实现根据性别查询并按照年龄倒序排序的功能。 总之,通过在实体类中定义排序字段的属性,并使用QueryWrapper类的排序方法,我们可以很容易地实现MyBatis Plus的动态排序功能。这样就可以根据实际需求按照不同的字段和顺序进行排序。 ### 回答3: MybatisPlus是一款开源的持久层框架,可以快速方便地实现数据库操作。在使用MybatisPlus实现动态排序时,可以通过Wrapper类和QueryWrapper类提供的orderBy方法来实现。 首先,我们需要创建一个Wrapper类或QueryWrapper类的实例,用于封装查询条件和排序规则。然后,可以使用orderBy方法来添加排序规则。orderBy方法接受一个boolean类型的参数,用于设置是否升序排序,默认为true(升序)。我们可以根据具体的需求,给orderBy方法传入字段名来完成排序操作。 下面是一个示例代码: ```java QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.orderBy(true, "age"); // 按照age字段升序排序 List<User> userList = userMapper.selectList(queryWrapper); ``` 在这个示例中,我们创建了一个QueryWrapper类的实例queryWrapper,并调用orderBy方法来设置按照age字段进行升序排序。最后,使用selectList方法执行查询操作,返回满足条件的用户列表。 除了orderBy方法,MybatisPlus还提供了其他一些方法来实现更复杂的排序需求,比如orderByAsc和orderByDesc方法可以分别实现升序和降序排序。 总之,通过使用MybatisPlus的Wrapper类和QueryWrapper类提供的排序方法,我们可以很方便地实现动态排序。根据具体的需求,可以按照不同的字段和排序规则来完成排序操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值