C# 将字符串排序为linq to实体中的数字
我有像“1”、“2”、“3”、“10”等som字符串,当使用orderby排序列表时是“1”、“10”、“2”、“3”。我想把它们按数字排序,比如1,2,3,…,10。我使用下面的代码对列表进行排序C# 将字符串排序为linq to实体中的数字,c#,linq,linq-to-entities,C#,Linq,Linq To Entities,我有像“1”、“2”、“3”、“10”等som字符串,当使用orderby排序列表时是“1”、“10”、“2”、“3”。我想把它们按数字排序,比如1,2,3,…,10。我使用下面的代码对列表进行排序 var model = (from c in General.db.GlbTbComboBases where c.ClassCode.Equals(classCode) select new ReturnData { id = c.BaseCod
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName }).OrderBy(c => c.id,
new SemiNumericComparer());
if (model.Any())
{
CacheManager.cache.GetOrAdd<List<ReturnData>>(key, () =>
model.ToList<ReturnData>());
return model.ToList<ReturnData>();
}
public class SemiNumericComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
}
if (IsNumeric(s1) && !IsNumeric(s2))
return -1;
if (!IsNumeric(s1) && IsNumeric(s2))
return 1;
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try
{
int i = Convert.ToInt32(value.ToString());
return true;
}
catch (FormatException)
{
return false;
}
}
}
这是一个遗留数据库,我无法更改任何数据类型,因为它可能会在其他应用程序上引发错误。这里有两个问题:
SemiNumericComparer
类转换为sql查询
为了达到预期效果,您可以:
a) 加载内存中的所有数据,并在内存中使用SemiNumericComparer
执行比较,方法是迭代选定的结果,然后按如下顺序排序:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.ToList() // this will load data into memory
.OrderBy(c => c.id, new SemiNumericComparer());
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new { Id = Convert.ToInt32(c.BaseCode), Name = c.FAName })
.OrderBy(c => c.Id)
.Select(x => new ReturnData { id = x.Id, name = x.Name });
但是,这不是一个好方法,因为如果数据集非常小,它会增加大量无用的内存消耗,如果数据集在给定时间大于可用内存,则会使应用程序崩溃
b) 使用将字符串转换为Sql Server上的数字,并使用Sql Server提供的顺序将其作为数字排序:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.OrderBy(c => SqlFunctions.IsNumeric(c.id));
这里有两个问题:
SemiNumericComparer
类转换为sql查询
为了达到预期效果,您可以:
a) 加载内存中的所有数据,并在内存中使用SemiNumericComparer
执行比较,方法是迭代选定的结果,然后按如下顺序排序:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.ToList() // this will load data into memory
.OrderBy(c => c.id, new SemiNumericComparer());
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new { Id = Convert.ToInt32(c.BaseCode), Name = c.FAName })
.OrderBy(c => c.Id)
.Select(x => new ReturnData { id = x.Id, name = x.Name });
但是,这不是一个好方法,因为如果数据集非常小,它会增加大量无用的内存消耗,如果数据集在给定时间大于可用内存,则会使应用程序崩溃
b) 使用将字符串转换为Sql Server上的数字,并使用Sql Server提供的顺序将其作为数字排序:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.OrderBy(c => SqlFunctions.IsNumeric(c.id));
如果需要数字顺序,则必须对数字数据类型进行排序:
string[] str = {"1", "10", "2","011"};
List<string> ordered = str.OrderBy(x => int.Parse(x)).ToList();
string[]str={“1”、“10”、“2”、“011”};
List ordered=str.OrderBy(x=>int.Parse(x)).ToList();
如果需要数字顺序,则必须对数字数据类型进行排序:
string[] str = {"1", "10", "2","011"};
List<string> ordered = str.OrderBy(x => int.Parse(x)).ToList();
string[]str={“1”、“10”、“2”、“011”};
List ordered=str.OrderBy(x=>int.Parse(x)).ToList();
尝试以下方法:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.ToList() // this will load data into memory
.OrderBy(c => c.id, new SemiNumericComparer());
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new { Id = Convert.ToInt32(c.BaseCode), Name = c.FAName })
.OrderBy(c => c.Id)
.Select(x => new ReturnData { id = x.Id, name = x.Name });
只需添加一个匿名类型进行排序,然后转换为所需类型。当然,这需要更多的内存。尝试以下方法:
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new ReturnData { id = c.BaseCode, name = c.FAName })
.ToList() // this will load data into memory
.OrderBy(c => c.id, new SemiNumericComparer());
var model = (from c in General.db.GlbTbComboBases
where c.ClassCode.Equals(classCode)
select new { Id = Convert.ToInt32(c.BaseCode), Name = c.FAName })
.OrderBy(c => c.Id)
.Select(x => new ReturnData { id = x.Id, name = x.Name });
只需添加一个匿名类型进行排序,然后转换为所需类型。当然,它需要更多的内存。看起来您正在以字符串的形式存储数字。根据需要将它们存储为int或decimal,然后它将为您提供所需的内容。这称为“自然排序顺序”。有一个相对简单的方法可以做到这一点。非常感谢Martin。看起来您正在以字符串的形式存储数字。根据需要将它们存储为int或decimal,然后它将为您提供所需的内容。这称为“自然排序顺序”。有一个相对简单的方法,非常感谢马丁。