翼度科技»论坛 编程开发 .net 查看内容

记录EF 排序配上自定义的比较器

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
记录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 方法返回的整数值来确定对象的相对顺序。根据返回值的正负来决定对象的位置。
  1. public int Compare(string x, string y)
  2. {
  3.     // 解析文件名中的数字部分
  4.     int fileNumberX = GetFileNumber(x);
  5.     int fileNumberY = GetFileNumber(y);
  6.     // 比较数字部分
  7.     int result = fileNumberX.CompareTo(fileNumberY);
  8.     if (result == 0)
  9.     {
  10.     // 如果数字部分相同,则按照完整文件名进行比较
  11.     result = x.CompareTo(y);
  12.     }
  13.     return result;
  14. }        
复制代码
通过传递文件名,使用正则表达式去匹配文件名中的序号部分,获取到1.1.1之后,在进行.去切割获取最后面的数字,然后返回回去,回到上面的Compare方法去比对文件名序号大小。
  1. private int GetFileNumber(string fileName)
  2. {
  3.     // 假设文件名的格式为数字序号 + "." + 文件类型(例如:1.1.1文件.pdf)
  4.     // 提取数字序号部分
  5.     try
  6.     {
  7.         // 使用正则表达式提取数字序号部分
  8.         string pattern = @"(\d+(\.\d+)*)";
  9.         Match match = Regex.Match(fileName, pattern);
  10.         MatchCollection matches = Regex.Matches(fileName, pattern);
  11.         if (matches.Count > 0)
  12.         {
  13.             string firstNumberPart=matches[0].Groups[1].Value;
  14.             // 提取最后面的数字
  15.             string[] parts = firstNumberPart.Split('.');
  16.             int lastPartIndex = parts.Length - 1;
  17.             int lastPart = int.Parse(parts[lastPartIndex]);
  18.             return lastPart;
  19.         }
  20.         // 如果无法解析数字序号,则返回一个默认值或抛出异常,具体根据您的需求来处理
  21.         // 这里返回一个负数作为默认值
  22.         return -1;
  23.     }
  24.     catch
  25.     {
  26.         return -1;
  27.     }
  28. }
  29. }            
复制代码
最关键的是需要实现 IComparer 接口的自定义比较器类,用于对字符串进行比较,上面的Compare和GetFileNumber写在方法内部即可。
  1. public class FileNameComparer : IComparer<string>
  2. {
  3.      ...//上面的2给方法都要放在这里面
  4. }
复制代码
使用起来也很简单,注意列名需要是字符串类型的。
  1. db.表名.OrderBy(s => s.列名,new FileNameComparer());
复制代码
结尾

EF自定义比较器可以进行排序、查找、去重等操作,同时支持实体对象和字符串进行比较操作,可以去看看官方文档的介绍:
IComparer 接口:https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.icomparer?view=net-7.0
OrderBy:https://learn.microsoft.com/zh-cn/dotnet/api/system.data.entity.core.common.commandtrees.expressionbuilder.dbexpressionbuilder.orderby?view=entity-framework-6.2.0

来源:https://www.cnblogs.com/ZYPLJ/archive/2023/10/23/17783188.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
来自手机

举报 回复 使用道具