記錄EF 排序配上自定義的比較器
前言
要求頁面文件顯示的時(shí)候能夠按照序號(hào)去排序要求如下:
數(shù)據(jù)庫有一個(gè)列存放文件名,如:
- 1.1文件
- 1.2文件
- 1.1.1文件
- 1.1.11文件1.0.txt
- 1.1.2(文件).pdf
現(xiàn)在需要實(shí)現(xiàn)查詢的時(shí)候按照這個(gè)列排序,并且是按照序號(hào)排序。
查詢的時(shí)候是按層級(jí)查詢的,每次查詢只會(huì)當(dāng)前所在層,1 文件夾、2文件夾、3文件,然后進(jìn)入1 文件夾 才會(huì)查詢出 1.1文件..1.2文件夾,這沒什么影響,主要實(shí)現(xiàn)的功能就是我查詢的時(shí)候要排序,如果直接根據(jù)列名OrderBy
是沒用的,所以需要用到EF的自定義比較器,通過自己編寫比較邏輯去完成排序。
代碼實(shí)現(xiàn)
首先是Compare
方法中的 x
和 y
參數(shù)分別表示當(dāng)前列的數(shù)據(jù)和當(dāng)前列的下一個(gè)數(shù)據(jù)。
假設(shè)查詢出來的數(shù)據(jù)第一條和第二條比對(duì)
- x:1.11文件
- y:1.1文件.pdf
這2個(gè)參數(shù)會(huì)進(jìn)入GetFileNumber
方法中將最前面的序號(hào)提取出來。
CompareTo
方法會(huì)按照字典順序進(jìn)行比較。對(duì)于數(shù)字類型,CompareTo
方法會(huì)按照數(shù)值大小進(jìn)行比較。
- 如果返回值為負(fù)數(shù)(例如-1),表示第一個(gè)對(duì)象(
x
)小于第二個(gè)對(duì)象(y
)。 - 如果返回值為零,表示兩個(gè)對(duì)象相等。
- 如果返回值為正數(shù)(例如1),表示第一個(gè)對(duì)象(
x
)大于第二個(gè)對(duì)象(y
)。
EF 在進(jìn)行排序時(shí),會(huì)根據(jù) Compare
方法返回的整數(shù)值來確定對(duì)象的相對(duì)順序。根據(jù)返回值的正負(fù)來決定對(duì)象的位置。
public int Compare(string x, string y)
{
// 解析文件名中的數(shù)字部分
int fileNumberX = GetFileNumber(x);
int fileNumberY = GetFileNumber(y);
// 比較數(shù)字部分
int result = fileNumberX.CompareTo(fileNumberY);
if (result == 0)
{
// 如果數(shù)字部分相同,則按照完整文件名進(jìn)行比較
result = x.CompareTo(y);
}
return result;
}
通過傳遞文件名,使用正則表達(dá)式去匹配文件名中的序號(hào)部分,獲取到1.1.1之后,在進(jìn)行.去切割獲取最后面的數(shù)字,然后返回回去,回到上面的Compare
方法去比對(duì)文件名序號(hào)大小。
private int GetFileNumber(string fileName)
{
// 假設(shè)文件名的格式為數(shù)字序號(hào) + "." + 文件類型(例如:1.1.1文件.pdf)
// 提取數(shù)字序號(hào)部分
try
{
// 使用正則表達(dá)式提取數(shù)字序號(hào)部分
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;
// 提取最后面的數(shù)字
string[] parts = firstNumberPart.Split('.');
int lastPartIndex = parts.Length - 1;
int lastPart = int.Parse(parts[lastPartIndex]);
return lastPart;
}
// 如果無法解析數(shù)字序號(hào),則返回一個(gè)默認(rèn)值或拋出異常,具體根據(jù)您的需求來處理
// 這里返回一個(gè)負(fù)數(shù)作為默認(rèn)值
return -1;
}
catch
{
return -1;
}
}
}
最關(guān)鍵的是需要實(shí)現(xiàn) IComparerCompare
和GetFileNumber
寫在方法內(nèi)部即可。
public class FileNameComparer : IComparer<string>
{
...//上面的2給方法都要放在這里面
}
使用起來也很簡單,注意列名需要是字符串類型的。
db.表名.OrderBy(s => s.列名,new FileNameComparer());
結(jié)尾
EF自定義比較器可以進(jìn)行排序、查找、去重等操作,同時(shí)支持實(shí)體對(duì)象和字符串進(jìn)行比較操作,可以去看看官方文檔的介紹:
IComparer 接口:https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.icomparer?view=net-7.0文章來源:http://www.zghlxwxcb.cn/news/detail-711407.html
OrderBy:https://learn.microsoft.com/zh-cn/dotnet/api/system.data.entity.core.common.commandtrees.expressionbuilder.dbexpressionbuilder.orderby?view=entity-framework-6.2.0文章來源地址http://www.zghlxwxcb.cn/news/detail-711407.html
到了這里,關(guān)于記錄EF 排序配上自定義的比較器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!