記錄EF 排序配上自定義的比較器 前言 要求頁面文件顯示的時候能夠按照序號去排序要求如下: 資料庫有一個列存放文件名,如: 1.1文件 1.2文件 1.1.1文件 1.1.11文件1.0.txt 1.1.2(文件).pdf 現在需要實現查詢的時候按照這個列排序,並且是按照序號排序。 查詢的時候是按層 ...
記錄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;
}
}
}
最關鍵的是需要實現 IComparerCompare
和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