Linq to SQL - 如何将数字作为字符串排序?

Posted

技术标签:

【中文标题】Linq to SQL - 如何将数字作为字符串排序?【英文标题】:Linq to SQL - How to order numbers as strings? 【发布时间】:2011-08-25 00:45:31 【问题描述】:

我有一个 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;

【问题讨论】:

你可能想看看这个问题:***.com/questions/2329580/… - 它应该提供一个开始。 您应该将您找到的答案添加为下面的实际答案,如果您愿意,请将其标记为答案,并对您认为有帮助的任何答案进行投票。 【参考方案1】:

我找到了一个解决方案,虽然我不确定它的效率。

from s in q orderby (SqlMethods.Like(s.fld, "%[^0-9]%") ? Int32.MaxValue : Convert.ToInt32(s.fld)) ascending, s.fld ascending select s; 

【讨论】:

【参考方案2】:

如果您已经从数据库中返回了结果,并且您很乐意在内存中进行排序,那么这就是一个可行的方法。

首先,定义一个可用于 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;

简单吧?

【讨论】:

+1,但您真的是要同时拥有两个 orderby 语句吗?只有后者是必要的,对吧? @ckittel - 我添加了第一个来订购不可解析的字段。这不是绝对必要的,但它会使所有数据按定义的顺序返回。 啊,是的,这是有道理的。谢谢你的解释。 谢谢,但我希望在数据库中执行此操作,因为我只返回一个大表中的结果页面。【参考方案3】:

我知道这个问题是关于 Linq-to-SQL 的,但我想我会为任何偶然发现这个问题的 EF 用户提供一个 Entity Framework 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()ing 值可能是最安全的,除非您知道您的数据永远不会是“int”varchar。

【讨论】:

这看起来是个不错的解决方案,但 Linq to SQL 似乎不支持 IsNumeric,错误是“System.Nullable`1[System.Int32] IsNumeric(System.String)' has no supported翻译成 SQL。”关于转换为双精度而不是整数的非常好的建议。 是的,我想这不会对你有直接的帮助。希望其他人觉得它有用。

以上是关于Linq to SQL - 如何将数字作为字符串排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何轻松地重新排序 LINQ to SQL 设计器中的列?

如何将 LINQ-to-SQL 映射到 BLL 类?

LinQ to SQL用法详解

如何改进 Linq-To-Sql 代码

linq to sql 怎么查前5条记录

T-SQL IsNumeric()和Linq-to-SQL