C# ASP.Net EF OrderBy非自然排序
我写的搜索功能。我的数据库字段为字符串(Nvarchar(MAX)),该字段有字符串和数字C# ASP.Net EF OrderBy非自然排序,c#,asp.net,asp.net-mvc,entity-framework,C#,Asp.net,Asp.net Mvc,Entity Framework,我写的搜索功能。我的数据库字段为字符串(Nvarchar(MAX)),该字段有字符串和数字 DB DATAS EF ORDER I want to a 1 a 1 a 1 a 20 a 12 a 2 a 2 a 2 a 12 a 12 a 20 a 20 a 25 a 25
DB DATAS EF ORDER I want to
a 1 a 1 a 1
a 20 a 12 a 2
a 2 a 2 a 12
a 12 a 20 a 20
a 25 a 25 a 25
b 1 b 1 b 1
b 5 b 5 b 5
.... ... ....
您需要实现IComparer接口,并创建一个
NaturalStringComparer
,以您想要的方式比较字符串。请参阅下面的代码
public class NaturalStringComparer : IComparer<string>
{
private static readonly Regex _re = new Regex(@"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);
public int Compare(string x, string y)
{
x = x.ToLower();
y = y.ToLower();
if (string.Compare(x, 0, y, 0, Math.Min(x.Length, y.Length)) == 0)
{
if (x.Length == y.Length) return 0;
return x.Length < y.Length ? -1 : 1;
}
var a = _re.Split(x);
var b = _re.Split(y);
int i = 0;
while (true)
{
int r = PartCompare(a[i], b[i]);
if (r != 0) return r;
++i;
}
}
private static int PartCompare(string x, string y)
{
int a, b;
if (int.TryParse(x, out a) && int.TryParse(y, out b))
return a.CompareTo(b);
return x.CompareTo(y);
}
}
公共类NaturalStringComparer:IComparer
{
private static readonly Regex\u re=new Regex(@)(?您可以执行以下操作:
var lists = strs.Select(str => new Regex(@"([a-zA-Z]+)(\d+)").Match(Regex.Replace(str, @"\s+", "")))
.Select(result => new
{
str = result.Groups[1].Value,
num = result.Groups[2].Value
})
.ToList().OrderBy(s=>s.str).ThenBy(s=>s.num).Select(s=> new {result=s.str+" "+s.num}).ToList();
在您的情况下(字母后接数字),您可能需要这样的数字填充(归功于Nathan):
通过这种方式,可以对OrderBy
子句中的数字部分进行填充,其使用方式如下:
var naturalOrder = list.OrderBy(x => PadNumbers(x));
a 01
a 20
a 02
a 12
a 25
...
a 01
a 02
a 12
a 20
a 25
...
通过使用上面的padding regex,OrderBy
将看到如下数字部分:
var naturalOrder = list.OrderBy(x => PadNumbers(x));
a 01
a 20
a 02
a 12
a 25
...
a 01
a 02
a 12
a 20
a 25
...
然后像这样订购:
var naturalOrder = list.OrderBy(x => PadNumbers(x));
a 01
a 20
a 02
a 12
a 25
...
a 01
a 02
a 12
a 20
a 25
...
当然,填充仅在决定数字顺序时用于比较,原始字符串仍然保留
填充用法背后的原因是默认顺序与OrderBy
一起使用,按字典顺序从左到右处理字符串中的字符
工作示例:
类似问题:
在LINQ中,您可以使用OrderBy
后跟ThenBy
,例如list.OrderBy(x=>x.LetterFieldName)。ThenBy(x=>x.NumericFieldName)
。如果要执行进一步的比较,请为数值字段创建一个扩展方法IComparer
,并将其传递到OrderBy
@tetsuyayayamamoto i have one field=>a2
数据仅为dbi中的一列have one field,此数据one items为data ex:a1
包含空格?@OnePageNumeric value为specific。它可能是也可能不是。我已经在使用它了。请检查邮件和代码区域。这个中间列表是EF orderbylist@OnePage:我已经编辑了我的答案。请查看我发布的测试示例。它对我来说很好,应该也适合你的要求。