我有一个SQL varchar列,其值为100,2000和S5000。我希望它们按数字顺序排序,而不是按字母顺序排列。如果有字符串字符,我很高兴字符被忽略或出现在排序顺序中的数值之后。
在T-SQL中我可以这样做:
SELECT * FROM tbl
ORDER BY
CASE
WHEN ISNUMERIC(fld) = 1 THEN CONVERT(INT, fld)
ELSE 2147483647
END ASC,
fld ASC
我想知道是否有办法在Linq to SQL中执行此操作?
否则我想我的选择是直接执行查询,或者创建一个计算列,其值为00000100,00002000,000S5000等。
编辑:虽然我不确定它的效率如何,但我找到了解决方案。
from s in q
orderby (SqlMethods.Like(s.fld, "%[^0-9]%") ? Int32.MaxValue : Convert.ToInt32(s.fld)) ascending, s.fld ascending
select s;
答案 0 :(得分:2)
虽然我不确定它的效率如何,但我找到了解决方案。
from s in q orderby (SqlMethods.Like(s.fld, "%[^0-9]%") ? Int32.MaxValue : Convert.ToInt32(s.fld)) ascending, s.fld ascending select s;
答案 1 :(得分:1)
如果您已经从数据库中返回了结果,并且您很乐意在内存中进行排序,那么这是一种方法。
首先,定义一个可以在linq-to-objects查询中使用的tryParse
函数:
Func<string, int> tryParse = s =>
{
int i;
if (!int.TryParse(s, out i))
{
i = int.MaxValue;
}
return i;
};
然后进行排序的实际查询很简单:
var query =
from t in tbls.ToArray() // force the linq-to-sql query to execute
orderby t.fld
orderby tryParse(t.fld)
select t;
简单,是吗?
答案 2 :(得分:0)
我知道问题是关于Linq-to-SQL,但我想我会为任何EF用户提供一个实体框架4答案,他们偶然发现了这个问题,寻找在该框架内完成此任务的方法。我没有使用Linq-to-SQL的经验,因此,据我所知,这实际上也可以在那里工作(但我对此表示怀疑)。
Dim results = (From item in ctx.tbl
Let sortValue = If(SqlFunctions.IsNumeric(item.fld) = 1, CInt(item.fld), 2147483647)
Order By sortValue).ToList()
这大致转变为此商店查询:
SELECT [Project1].*
FROM ( SELECT
[Extent1].*
CASE WHEN (1 = (ISNUMERIC([Extent1].[Value]))) THEN CAST( [Extent1].[Value] AS int) ELSE 99999999 END AS [C2]
FROM [dbo].[tbl] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[C2] ASC
此解决方案利用System.Data.Objects.SqlClient.SqlFunctions基本直接调用查询中的SQL ISNUMERIC function。我想指出IsNumeric
将返回1
甚至是小数,并将“十进制”varchar转换为int
会导致问题。 CDbl()
而不是CInt()
值可能是最安全的,除非您知道您的数据永远不会是“int”varchar。