记录EF 排序配上自定义的比较器
记录EF 排序配上自定义的比较器
前言
要求页面文件显示的时候能够按照序号去排序要求如下:
数据库有一个列存放文件名,如:
- 1.1文件
- 1.2文件
- 1.1.1文件
- 1.1.11文件1.0.txt
- 1.1.2(文件).pdf
现在需要实现查询的时候按照这个列排序,并且是按照序号排序。
查询的时候是按层级查询的,每次查询只会当前所在层,1 文件夹、2文件夹、3文件,然后进入1 文件夹 才会查询出 1.1文件..1.2文件夹,这没什么影响,主要实现的功能就是我查询的时候要排序,如果直接根据列名OrderBy是没用的,所以需要用到EF的自定义比较器,通过自己编写比较逻辑去完成排序。
代码实现
首先是Compare 方法中的 x 和 y 参数分别表示当前列的数据和当前列的下一个数据。
假设查询出来的数据第一条和第二条比对
- x:1.11文件
- y:1.1文件.pdf
这2个参数会进入GetFileNumber方法中将最前面的序号提取出来。
CompareTo方法会按照字典顺序进行比较。对于数字类型,CompareTo方法会按照数值大小进行比较。
- 如果返回值为负数(例如-1),表示第一个对象(
x)小于第二个对象(y)。 - 如果返回值为零,表示两个对象相等。
- 如果返回值为正数(例如1),表示第一个对象(
x)大于第二个对象(y)。
EF 在进行排序时,会根据 Compare 方法返回的整数值来确定对象的相对顺序。根据返回值的正负来决定对象的位置。
public int Compare(string x, string y)
{
// 解析文件名中的数字部分
int fileNumberX = GetFileNumber(x);
int fileNumberY = GetFileNumber(y);
// 比较数字部分
int result = fileNumberX.CompareTo(fileNumberY);
if (result == 0)
{
// 如果数字部分相同,则按照完整文件名进行比较
result = x.CompareTo(y);
}
return result;
}
通过传递文件名,使用正则表达式去匹配文件名中的序号部分,获取到1.1.1之后,在进行.去切割获取最后面的数字,然后返回回去,回到上面的Compare方法去比对文件名序号大小。
private int GetFileNumber(string fileName)
{
// 假设文件名的格式为数字序号 + "." + 文件类型(例如:1.1.1文件.pdf)
// 提取数字序号部分
try
{
// 使用正则表达式提取数字序号部分
string pattern = @"(\d+(\.\d+)*)";
Match match = Regex.Match(fileName, pattern);
MatchCollection matches = Regex.Matches(fileName, pattern);
if (matches.Count > 0)
{
string firstNumberPart=matches[0].Groups[1].Value;
// 提取最后面的数字
string[] parts = firstNumberPart.Split('.');
int lastPartIndex = parts.Length - 1;
int lastPart = int.Parse(parts[lastPartIndex]);
return lastPart;
}
// 如果无法解析数字序号,则返回一个默认值或抛出异常,具体根据您的需求来处理
// 这里返回一个负数作为默认值
return -1;
}
catch
{
return -1;
}
}
}
最关键的是需要实现 IComparer 接口的自定义比较器类,用于对字符串进行比较,上面的Compare和GetFileNumber写在方法内部即可。
public class FileNameComparer : IComparer<string>
{
...//上面的2给方法都要放在这里面
}
使用起来也很简单,注意列名需要是字符串类型的。
db.表名.OrderBy(s => s.列名,new FileNameComparer());
结尾
EF自定义比较器可以进行排序、查找、去重等操作,同时支持实体对象和字符串进行比较操作,可以去看看官方文档的介绍:
IComparer 接口:https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.icomparer?view=net-7.0
记录EF 排序配上自定义的比较器的更多相关文章
- Day 8:方法上自定义泛型、类上、接口上、泛型的上下限
泛型 泛型是jdk1.5使用的新特性 泛型的好处: 1. 将运行时的异常提前至了编译时 2. 避免了无谓的强制类型转换 泛型在集合中的常见应用: ArrayList<Strin ...
- Linux(2)---记录一次线上服务 CPU 100%的排查过程
Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...
- 记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb
记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb 前段时间我个人Google服务器意外不能用,并且我犯了一件很低级的错误,直接在gcp讲服 ...
- 在EntityFrameworkCore中记录EF修改日志,保存,修改字段的原始值,当前值,表名等信息
突发奇想,想把业务修改的所有字段原始值和修改后的值,做一个记录,然后发现使用EF可以非常简单的实现这个功能 覆盖父类中的 SaveShanges() 方法 public new int SaveCha ...
- 给Angularjs配上Requirejs
给Angularjs配上Requirejs 需要考虑的事情: 1.js.css.template都按需加载,js主要就controller: * js和css都可以用requirejs和它的插件解决, ...
- 19.翻译系列:EF 6中定义自定义的约定【EF 6 Code-First约定】
原文链接:https://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx EF 6 ...
- 记录一次线上bug
记录一次线上bug,总的来说就是弱网和重复点击.特殊值校验的问题. 测试场景一: 在3g网络或者使页面加载速度需要两秒左右的时候,输入学号,提交学生的缴费项目,提交完一个 学生的缴费后, ...
- mysql选择上一条、下一条数据记录,排序上移、下移、置顶
1.功能须要 完毕列表排序上移,下移,置顶功能.效果例如以下图所看到的: 2设置思路 设置一个rank为之间戳,通过选择上移,就是将本记录与上一条记录rank值交换,下移就是将本条记录与下一条记录ra ...
- Java之ArrayList自定义排序,通过实现comparator比较器接口
两种排序方式: 1.实体类实现Comparable接口,重写compareTo(T o)方法,在其中定义排序规则,那么就可以直接调用Collections.sort()来排序对象数组 2.在调用方法的 ...
- SkyWalking配上告警更优秀
前言 对于监控系统来说,不可能让人一直盯着监控看板,而更多的是以自动提醒的方式,比如邮件.短信或微信推送等,当达到或超出预设的告警指标时,就自动发送消息提醒,下面就来说说如何配置SkyWalking的 ...
随机推荐
- c#胖东来小程序自动购物程序(接单,windows桌面程序、linux程序、网络应用等等)
一.程序效果 自动打开胖东来小程序,自动购物 二.实现 先截屏,然后利用opencv库识别下一步按键所在位置,然后使用mouse_event控制鼠标,模拟人的动作 第一步,截取屏幕 static Bi ...
- 一键自动化博客发布工具,chrome和firfox详细配置
blog-auto-publishing-tools博客自动发布工具现在已经可以同时支持chrome和firefox了. 很多小伙伴可能对于如何进行配置和启动不是很了解,今天带给大家一个详细的保姆教程 ...
- 羽夏闲谈——TeeWorlds 中文问题
不久前 削微寒 园友发布了一篇博文 误入 GitHub 游戏区,意外地收获颇丰 ,看到了一个游戏 TeeWorlds .有一说一挺好玩的,下面是那个博客的原图: 官方的下载连接:https:/ ...
- golang中三种定时器的实现方式及周期定时
一.定时器的创建 golang中定时器有三种实现方式,分别是time.sleep.time.after.time.Timer 其中time.after和time.Timer需要对通道进行释放才能达到定 ...
- docker-compose 安装 mysql:5.7.31
目录 一.新建一个启动服务的目录 二.新建文件docker-compose.yml 三.新建角本文件 init-mysql.sh 四.实使化目录和配置文件 启动服务 登陆mysql 其它操作 参考文档 ...
- 深度Linux deepin更新,防火墙操作
获取更新 sudo apt-get update 更新系统 sudo apt-get dist-upgrade -y 清理更新缓存 sudo apt-get autoclean 防火墙操作 sudo ...
- SRAM、DRAM、Flash、DDR有什么区别
SRAM SRAM的全称是Static Rnadom Access Memory,翻译过来即静态随机存储器.这里的静态是指这种存储器只需要保持通电,里面的数据就可以永远保持.但是当断点之后,里面的数据 ...
- HC32L110(六) AS06-VTB07H V5.0测试板AT指令固件
目录 HC32L110(一) HC32L110芯片介绍和Win10下的烧录 HC32L110(二) HC32L110在Ubuntu下的烧录 HC32L110(三) HC32L110的GCC工具链和VS ...
- 超全、超简单Vue微信公众号授权登录指南
<template> <div id="app"> <h1>微信授权登陆</h1> <div> <div> ...
- HTML——form表单
表单主要是用来收集客户端提供的相关信息,提供了用户数据录入的方式,有多选.单选.单行文本.下拉列表等输入框,便于网站管理员收集用户的数据,是Web浏览器和Web服务器之间实现信息交流和数据传递的桥梁. ...