TNBLOG
首页
博客
视频
资源
问答
猿趣
手机
关于
搜索
收藏
便签
笔记
消息
创作
登录
剑轩
应无所住,而生其心
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
CSS
16篇
微服务
41篇
Git
15篇
.NET
105篇
移动开发
33篇
软件架构
23篇
.NET Core
119篇
.NET MVC
11篇
英语
3篇
随笔
90篇
Bootstrap
3篇
Redis
21篇
编辑器
10篇
Js相关
15篇
虚拟化
8篇
更多
Oracle
7篇
Python
14篇
数据库
26篇
EF
17篇
微信
3篇
前端
160篇
消息队列
6篇
docker
41篇
多线程
1篇
Java
4篇
软件基础
2篇
C++
2篇
WCF
7篇
Linux
7篇
nginx
5篇
K8S
9篇
ABP
2篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术
原
表达式树+反射实现动态排序。List动态排序,集合动态排序
5322
人阅读
2022/12/5 15:04
总访问:
4438113
评论:
1
收藏:
0
手机
分类:
.NET Core
**比如要点击表头进行排序,排序的字段比如多,一个一个判断去写就比较麻烦。判断就太多了,如果其他地方也要用排序重复代码就会很多,类似这种。** ``` if (sort.ToLower() == "max") { if (sortway == "asc") { query = query.OrderBy(a => a.Max); } else { query = query.OrderByDescending(a => a.Max); } } if (sort.ToLower() == "min") { if (sortway == "asc") { query = query.OrderBy(a => a.Min); } else { query = query.OrderByDescending(a => a.Min); } } if (sort.ToLower() == "sum") { if (sortway == "asc") { query = query.OrderBy(a => a.Min); } else { query = query.OrderByDescending(a => a.Min); } } ``` **所以我们封装一下通用的排序方法** ``` using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace SmartEDU.LabRoom.Service.Tools { /// <summary> /// AJ:集合动态排序工具类 /// </summary> public static class OrderTools { public static IEnumerable<TSource> OrderByStr<TSource>(this IEnumerable<TSource> query, string sort, string sortway) { if (!string.IsNullOrEmpty(sort)) { //第一步要拿到排序字段的类型。忽略大小写一下 Type propertyType = typeof(TSource).GetProperty(sort, BindingFlags.Public|BindingFlags.IgnoreCase|BindingFlags.Instance).PropertyType; //通过反射拿到方法 var method = typeof(OrderTools).GetMethod(sortway == "asc" ? "DealAsc" : "DealDesc"); //给反射拿到的方法提供泛型 method = method.MakeGenericMethod(typeof(TSource), propertyType); //反射调用方法 IEnumerable<TSource> result = (IEnumerable<TSource>)method.Invoke(null, new object[] { query, sort }); return result; } return query; } /// <summary> /// 处理升序排序 /// 通过一个方法中转实现类型的传递 /// </summary> public static IEnumerable<TSource> DealAsc<TSource, M>(IEnumerable<TSource> query, string sort) { return query.OrderBy(OrderLamdba<TSource, M>(query, sort).Compile()); } /// <summary> /// 处理降序排序 /// 通过一个方法中转实现类型的传递 /// </summary> public static IEnumerable<TSource> DealDesc<TSource, M>(IEnumerable<TSource> query, string sort) { return query.OrderByDescending(OrderLamdba<TSource, M>(query, sort).Compile()); } static Expression<Func<TSource, M>> OrderLamdba<TSource, M>(IEnumerable<TSource> query, string sort) { var left = Expression.Parameter(typeof(TSource), "a"); var body = Expression.Property(left, sort); Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, left); return lamdba; } } } ``` **使用就很方便了** ``` //降序 if (item.IsDesc) { labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "desc").ToList(); } //升序 else { labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "asc").ToList(); } ``` 这里升序降序其实都可以不用判断,按照升降序的格式传递就行,我这里是修改同事写的代码,前台传递过来就是这种格式了,就不单独处理了,而且其实这种升降序判断一下代码可读性还高一点。 这里是集合在内存中排序的,如果是ef这类的排序参考:https://www.tnblog.net/aojiancc2/article/details/2752 这个里边封装的也是根据那篇博文稍微修改了一点,其实主要就是把IQueryable换成了IEnumerable **有时候数据量不大的时候前台又需要分页和排序,就可以把数据查询出来,然后在内存中排序之后在分页** ``` // 内存中排序 if (item.IsDesc) { labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "desc").ToList(); } else { labStatisticsList = labStatisticsList.OrderByStr(item.OrderField, "asc").ToList(); } //在内存中排序后在分页 labStatisticsList = labStatisticsList.Skip((quer.PageIndex - 1) * quer.PageSize).Take(quer.PageSize).ToList(); ``` 当然这只是一种方案,一般页数只有几页的时候可以使用,数据量大了还是要在数据库中分页。有时候去修改其他人写的代码不要去动太多逻辑的时候也可以考虑在内存中分页。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}