应无所住,而生其心
排名
21
文章
27
粉丝
11
评论
12
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

表达式树+反射实现动态排序。List动态排序,集合动态排序

6647人阅读 2022/12/5 15:04 总访问:5182489 评论:1 收藏:0 手机
分类: .NET Core

比如要点击表头进行排序,排序的字段比如多,一个一个判断去写就比较麻烦。判断就太多了,如果其他地方也要用排序重复代码就会很多,类似这种。

  1. if (sort.ToLower() == "max")
  2. {
  3. if (sortway == "asc")
  4. {
  5. query = query.OrderBy(a => a.Max);
  6. }
  7. else
  8. {
  9. query = query.OrderByDescending(a => a.Max);
  10. }
  11. }
  12. if (sort.ToLower() == "min")
  13. {
  14. if (sortway == "asc")
  15. {
  16. query = query.OrderBy(a => a.Min);
  17. }
  18. else
  19. {
  20. query = query.OrderByDescending(a => a.Min);
  21. }
  22. }
  23. if (sort.ToLower() == "sum")
  24. {
  25. if (sortway == "asc")
  26. {
  27. query = query.OrderBy(a => a.Min);
  28. }
  29. else
  30. {
  31. query = query.OrderByDescending(a => a.Min);
  32. }
  33. }

所以我们封装一下通用的排序方法

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace SmartEDU.LabRoom.Service.Tools
  9. {
  10. /// <summary>
  11. /// AJ:集合动态排序工具类
  12. /// </summary>
  13. public static class OrderTools
  14. {
  15. public static IEnumerable<TSource> OrderByStr<TSource>(this IEnumerable<TSource> query, string sort, string sortway)
  16. {
  17. if (!string.IsNullOrEmpty(sort))
  18. {
  19. //第一步要拿到排序字段的类型。忽略大小写一下
  20. Type propertyType = typeof(TSource).GetProperty(sort, BindingFlags.Public|BindingFlags.IgnoreCase|BindingFlags.Instance).PropertyType;
  21. //通过反射拿到方法
  22. var method = typeof(OrderTools).GetMethod(sortway == "asc" ? "DealAsc" : "DealDesc");
  23. //给反射拿到的方法提供泛型
  24. method = method.MakeGenericMethod(typeof(TSource), propertyType);
  25. //反射调用方法
  26. IEnumerable<TSource> result = (IEnumerable<TSource>)method.Invoke(null, new object[] { query, sort });
  27. return result;
  28. }
  29. return query;
  30. }
  31. /// <summary>
  32. /// 处理升序排序
  33. /// 通过一个方法中转实现类型的传递
  34. /// </summary>
  35. public static IEnumerable<TSource> DealAsc<TSource, M>(IEnumerable<TSource> query, string sort)
  36. {
  37. return query.OrderBy(OrderLamdba<TSource, M>(query, sort).Compile());
  38. }
  39. /// <summary>
  40. /// 处理降序排序
  41. /// 通过一个方法中转实现类型的传递
  42. /// </summary>
  43. public static IEnumerable<TSource> DealDesc<TSource, M>(IEnumerable<TSource> query, string sort)
  44. {
  45. return query.OrderByDescending(OrderLamdba<TSource, M>(query, sort).Compile());
  46. }
  47. static Expression<Func<TSource, M>> OrderLamdba<TSource, M>(IEnumerable<TSource> query, string sort)
  48. {
  49. var left = Expression.Parameter(typeof(TSource), "a");
  50. var body = Expression.Property(left, sort);
  51. Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, left);
  52. return lamdba;
  53. }
  54. }
  55. }

使用就很方便了

  1. //降序
  2. if (item.IsDesc)
  3. {
  4. labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "desc").ToList();
  5. }
  6. //升序
  7. else
  8. {
  9. labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "asc").ToList();
  10. }

这里升序降序其实都可以不用判断,按照升降序的格式传递就行,我这里是修改同事写的代码,前台传递过来就是这种格式了,就不单独处理了,而且其实这种升降序判断一下代码可读性还高一点。

这里是集合在内存中排序的,如果是ef这类的排序参考:https://www.tnblog.net/aojiancc2/article/details/2752
这个里边封装的也是根据那篇博文稍微修改了一点,其实主要就是把IQueryable换成了IEnumerable

有时候数据量不大的时候前台又需要分页和排序,就可以把数据查询出来,然后在内存中排序之后在分页

  1. // 内存中排序
  2. if (item.IsDesc)
  3. {
  4. labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "desc").ToList();
  5. }
  6. else
  7. {
  8. labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "asc").ToList();
  9. }
  10. //在内存中排序后在分页
  11. labStatisticsList = labStatisticsList.Skip((quer.PageIndex - 1) * quer.PageSize).Take(quer.PageSize).ToList();

当然这只是一种方案,一般页数只有几页的时候可以使用,数据量大了还是要在数据库中分页。有时候去修改其他人写的代码不要去动太多逻辑的时候也可以考虑在内存中分页。


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

叼着奶瓶逛酒吧

2019/4/23 15:24:22

文章写得真心不错,加油哈[赞]

表达式树+反射扩展EF实现动态排序。List动态排序

我们在显示表格的时候经常会在点击表头的时候实现排序,当然很多前端的框架都实现了当前页的页面排序,直接配置一下就行了...

.net liststring 转listint。.net 字符串集合转Int集合。.net string集合转int集合。.net list string转list int。List string 转list double

.net list string 转list int代码如下: var strList = new List&lt;string&gt;{&quot;1&quot;,&quot;2&quot;,&quot;3&quo...

表达式树【Expression】+反射-实现动态排序

首先 要实现一个传2个参数的方法,进行动态排序在写一个方法接收传过来的数据进行处理返回我们先是拿到sort类型—&gt;想要...

EF扩展反射实现动态排序+表达式树

现在各种网站上的表格可以通过点击排头来实现排序例如:今天我就来一探究竟,这是怎么实现的呢?具体步骤:我通过写扩展方...

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

后台代码如下:方法1:逐个判断 --&gt;缺点:代码重复,体验感差 if(sort.ToLower()==&quot;max&quot;) { if(sortway==...

abp vnext 通用仓储 ef core。WhereIf多条件动态条件分页动态排序

abp vnext 通用仓储 ef core WhereIf,多条件,分页等public async Task&lt;List&lt;LandInfoDto&gt;&gt; GetListAsync(Pag...

css弹性盒子flex布局

css弹性盒子由于版本不同浏览器问题造成了一些不同的写法display:flexbox;在google浏览器中如果使用下面的写法就不行displa...

可输入下拉文本框据输入动态加载数据 jquery-editable-select

用到一个jquery-editable-select的控件github地址:https://github.com/indrimuska/jquery-editable-select这个插件的原理是...

.net mvc分部页.net core分部页

.net分部页的三种方式第一种:@Html.Partial(&quot;_分部页&quot;)第二种:@{ Html.RenderPartial(&quot;分部页&quot;);}...

css中单位pxemrem和vh/vw的理解

&gt;px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。em是相对长度单位。相对于当前对象内文本的字...

让IIS支持webp格式图片让IIS支持vtt格式iis设置mime类型iis配置支持的类型

webp格式图片可以让图片体积变小。也让下载图片变得更加困难一点 在线制作webp工具 https://www.upyun.com/webp?utm_mediu...

网页上传文件断点续传的实现无视文件大小上传以及datatables基本用法

首先明白js是客户带执行代码,c#是服务器上执行代码。本地文件需要用到js处理,服务器端接受c#代码处理1.HTML页面,文件信...

如何使用图标像使用文字一样使用文本图标的方法

1.首先在Iconfont-阿里巴巴矢量图标库上面找到你需要的图标然后加入你的购物车然后选择图标;注意:每个类型的图标会大小不...

使用七牛云的cdn服务提高图片的加载速度

CDN介绍CDN的全称是Content Delivery Network,即内容分发网络。CDN加速主要是加速静态资源,如网站上面上传的图片、媒体,...

通俗易懂什么是.NET?什么是.NET Framework?什么是.NET Core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...