【问题标题】:SQL OrderBy clause for alphanumeric data in LINQ not sorting as expectedLINQ 中字母数字数据的 SQL Order By 子句未按预期排序
【发布时间】:2017-02-07 10:54:27
【问题描述】:

我有一个使用 SQL order by 排序的 SQL Server Reporting Services (SSRS) 报告,并为字母数字字符串数据返回以下内容:

Value: 0.0
Value: 20.96
Value: 289.64
Value: 30.99
Value: 308.655
Value: -32296.32
Value: 34.844
Value: 38.95
Value: -697.38
Value: -703.48

每个字符串的格式如下:

`Value: numeric data`

SQL order by 似乎按字符串排序,但忽略了数值前的减号。

我正在使用 C# 和 LINQ 对字符串进行排序以尝试匹配该排序:

var _sorted = _unsortedValues.OrderBy(x => x.Description);

我明白了:

Value: -32296.32
Value: -697.38
Value: -703.48
Value: 0.0
Value: 20.96
Value: 289.64
Value: 30.99
Value: 308.655
Value: 34.844
Value: 38.95

默认情况下,LINQ 对字符串进行排序,所有负值首先升序,然后是零,然后是正值

关于如何获得所需的排序以复制 SSRS 排序的任何想法?

注意

我在此报告列中有其他类型的字符串已正确排序。 例如

"Timestamp: data time data"
"Identifier: string data"

【问题讨论】:

  • 我刚刚在 Linqpad 中将其作为字符串列表进行了尝试,并按照您的要求对其进行了排序。由于我无法复制您的问题,我需要更多信息。描述是如何填充的,您能否显示更多代码来显示它是如何填充的以及它所在的类。
  • 给我们更多代码。您的代码应该根据您提供给我们的数据运行

标签: c# sql-server linq sorting alphanumeric


【解决方案1】:

我想这里的 LINQ 是指常规的 LINQ to objects,而不是 Entity Framework 或 LINQ to sql。字符串的排序方式取决于使用的比较器,您可以将任何您喜欢的比较器传递给OrderBy 语句。因此,例如要获得您想要的排序,您可以这样做:

var sorted = _unsortedValues.OrderBy(x => x.Description, StringComparer.InvariantCulture).ToArray();

这将返回与您的 SQL 语句相同的顺序。

如果你同时使用另一个比较器,像这样:

var sorted = _unsortedValues.OrderBy(x => x.Description, StringComparer.Ordinal).ToArray();

你会得到你问题中的顺序(负数优先)。

为什么你得到你得到的订单,但其他人无法复制?这是因为默认使用CurrentCulture字符串比较器,不同机器当前的文化可能不同,所以人们得到不同的结果。

var sorted = _unsortedValues.OrderBy(x => x.Description, StringComparer.CurrentCulture).ToArray(); // this is what is done by default

【讨论】:

  • 感谢 Evk 的解决方案。我也遇到了大小写问题,所以我使用了“StringComparer.InvariantCultureIgnoreCase”,它解决了我的大小写和排序问题。
【解决方案2】:

如您所见,您的字符串按字母顺序排序。这里没有魔法。号码 289.64 位于 30.99 之前。如果要按字符串中的数字排序,则应提取这些数字。您可以使用正则表达式,但简单的 Substring 应该可以在这里工作,因为所有字符串在数字前都有相同的前缀:

var startIndex = "Value: ".Length;
var _sorted = _unsortedValues
                .OrderBy(x => Double.Parse(x.Description.Substring(startIndex)));

注意:考虑去掉服务器端的Value:前缀,因为它不提供任何真实数据。

【讨论】:

  • 我想使用默认比较器(如 InvariantCulture)会更好。
  • @Evk 我不确定是否只有减号是 OP 排序的问题。您的解决方案仍将在 30.99 之前返回 289.64,而忽略数值。
  • 但是 OP 不需要数字排序 - 他需要与他的 SQL 查询返回相同的排序,而这个解决方案正好提供了这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2015-07-10
  • 1970-01-01
  • 2023-02-03
  • 2016-03-06
相关资源
最近更新 更多