【问题标题】:Linq to SQL - How to order numbers as strings?Linq to SQL - 如何将数字作为字符串排序?
【发布时间】: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;

【问题讨论】:

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

标签: .net linq-to-sql


【解决方案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。”关于转换为双精度而不是整数的非常好的建议。
    • 是的,我想这不会对你有直接的帮助。希望其他人觉得它有用。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多