tnblog
首页
视频
资源
登录

表达式树+反射+扩展方法实现动态排序效果

6974人阅读 2019/10/23 18:44 总访问:400266 评论:0 收藏:0 手机
分类: Mvc EF框架

后台代码如下:


 方法1:逐个判断 -->缺点:代码重复,体验感差

         

  1.   if (sort.ToLower() == "max")
  2.             {
  3.                 if (sortway == "asc")
  4.                 {
  5.                     query2=query2.OrderBy(a => a.max);
  6.                 }
  7.                 else
  8.                 {
  9.                     query2=query2.OrderByDescending(a => a.max);
  10.                 }
  11.             }
  12.             if (sort.ToLower() == "min")
  13.             {
  14.                 if (sortway == "asc")
  15.                 {
  16.                     query2 = query2.OrderBy(a => a.min);
  17.                 }
  18.                 else
  19.                 {
  20.                     query2 = query2.OrderByDescending(a => a.min);
  21.                 }
  22.             }



  方法2:缺点:参数类型固定的,对于不同类型排序时会报错


         

  1.   if (!string.IsNullOrWhiteSpace(sort))
  2.             {
  3.                 //反射获取属性
  4.                 var method = sort.GetType().GetProperties();
  5.                 //定义表达式树中的参数
  6.                 var left = Expression.Parameter(typeof(AllScoreModel), "a");
  7.                 //创造一个表示访问属性的Expression(表达式树)
  8.                 var body = Expression.Property(left, sort);
  9.                 //得到lamdba表达式
  10.                 Expression<Func<AllScoreModel, int?>> lamdba = Expression.Lambda<Func<AllScoreModel, int?>>(body, left);
  11.                 //此时的lamdba自动组合为:a=>a.sort形式,sort为传的值
  12.                 if (sortway == "asc")
  13.                 {
  14.                     query2 = query2.OrderBy(lamdba);
  15.                 }
  16.                 else
  17.                 {
  18.                     query2 = query2.OrderByDescending(lamdba);
  19.                 }
  20.             }


我们现在写的动态排序只支持int类型,如果是小数类型排序就会报错,比如根据平均分排序

 所以这里我们不能写死。这里就需要动态的获取属性类型,可以巧妙的使用反射方法来中转,因为反射调用方法的时候可以传递类型参数


//方法3,扩展方法封装使用,然后linq语句或lamdba语句后面调用OrderBy(sort,sortway)传参即可

//sort(排序的字段),sortway(排序的方式)

//新建一个类,封装MyOrderBy扩展方法

 

  1. public static class MyExpressionoderby
  2.     {
  3.         //封装自动升序或者降序的排序,解决不同类型的转换问题
  4.         public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> query, string sort, string sortway)
  5.         {
  6.             if (!string.IsNullOrWhiteSpace(sort))
  7.             {
  8.                 //第一步,拿到排序字段的类型
  9.                 Type propertyType = typeof(TSource).GetProperty(sort).PropertyType;
  10.                 //如果直接调用方法,参数类型还是无法转换
  11.                 //反射调用方法,可以动态传递类型
  12.                 //通过反射,拿到方法
  13.                 var method = typeof(MyExpressionoderby).GetMethod(sortway == "asc" ? "DealAsc" : "DealDesc");
  14.                 //给反射拿到的方法提供泛型,需要现得到对象(method),再取出去调用
  15. //否则报错:


不能对 ContainsGenericParameters 为 True 的类型或方法执行后期绑定操作。

           

  1.     method = method.MakeGenericMethod(typeof(TSource), propertyType);   //MakeGenericMethod:泛型,参数变量
  2.                 //反射调用方法
  3.                 IQueryable<TSource> result = (IQueryable<TSource>)method.Invoke(nullnew object[] { query, sort });
  4.                 //Invoke(null, new object[] { query, sort })反射对象语句
  5.                 return result;
  6.             }
  7.             return query;
  8.         }
  9.         /// <summary>
  10.         /// 处理升序排序
  11.         /// 通过一个方法中转实现类型的传递
  12.         /// </summary>    
  13.         public static IQueryable<TSource> DealAsc<TSource, M>(IQueryable<TSource> query, string sort)
  14.         {
  15.             var left = Expression.Parameter(typeof(TSource), "a");
  16.             var body = Expression.Property(left, sort);
  17.             //此时的lamdba自动组合为:a=>a.sort形式,sort为传的值
  18.             Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, left);
  19.             query = query.OrderBy(lamdba);
  20.             return query;
  21.         }
  22.         /// <summary>
  23.         /// 处理降排序
  24.         /// 通过一个方法中转实现类型的传递
  25.         /// </summary>    
  26.         public static IQueryable<TSource> DealDesc<TSource, M>(IQueryable<TSource> query, string sort)
  27.         {
  28.             var left = Expression.Parameter(typeof(TSource), "a");
  29.             var body = Expression.Property(left, sort);
  30.             //此时的lamdba自动组合为:a=>a.sort形式,sort为传的值
  31.             Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, left);
  32.             query = query.OrderByDescending(lamdba);
  33.             return query;
  34.         }
  35.     }


使用的时候很简单在后面直接点出来就好

对于前台的话,就需要自定义属性传值:图如下:


前台最后一步神奇就是js传值和动态改变排序啦:


好了,效果完成,完美的动态排序就完成了 hahaha


以上为市场最昂贵的干货啦,觉得喜欢的朋友可以收藏一份哦

评价
你之所以觉得时间一年比一年过得快,是因为时间对你一年比一年重要。
排名
13
文章
64
粉丝
20
评论
30
MUI框架页面间的传值指针
XingDy姐 : 不错哦
MUI框架页面间的传值指针
剑轩 : 接口的真实地址可以用xx/yy什么的代替哦,真实地址还是隐藏一下好
.NET EF 用户按钮权限
YOU : 可以,在写文章的时候,有需要写代码的地方,可以选择编辑器上的代...
.NET EF 用户按钮权限
剑轩 : 哈哈哈哈,你这个追女生的逻辑
EF三种模式解析
剑轩 : 好文采!
重要sql语句和linq,lamdba分组条件查询语句
剑轩 : 开头那句诗句写得很好哇!
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
大本钟下送快递——上面摆,下面寄。