【问题标题】:Linq results are displayed in different orderingLinq 结果以不同的顺序显示
【发布时间】:2014-09-19 08:58:12
【问题描述】:

我目前正在摆弄 AdventureWorks 示例数据库和 LinqPad,以寻找一些想法。

这是有问题的查询:

SalesOrderHeaders.GroupBy (soh => new {soh.CustomerID, soh.BillToAddressID})
                 .Where(soh => soh.Skip(1).Any())
                 .Dump();

我们的想法是根据某些标准查找重复项,然后显示它们,但第一组数据除外。结果应该从表中删除。

执行查询后,我得到结果 A)

再次执行查询后,我得到了结果 B)

我不关心查询的正确结果,而是关心结果集的顺序。只有这两种可能性存在,并且它们在每次运行查询时交替出现。 当然我可以通过 Key 订购,但我更感兴趣的是为什么会发生这种情况?为什么顺序改变/交替?

【问题讨论】:

  • 您的期望导致呈现给用户的数据应该被排序的一般原则,即使没有其他理由对其进行排序,也没有行之间的任何逻辑排序。 (当然,这不适用于 LINQPad 和 SSMS 等开发人员工具。)

标签: c# linq linq-to-sql linqpad


【解决方案1】:

Sql 服务器选择查询的结果集顺序不确定。这就是 sql server 的工作方式,它不是 linq 或 linqpad 中的错误。正如您所指出的,在查询中获得确定性结果的唯一方法是使用 OrderBy 子句。

编辑:如果您多次运行查询,关于在 SSMS 中获得相同结果,请参阅this。这篇文章解释了为什么如果你多次执行查询可能会得到相同的结果,以及为什么你不应该依赖它。

【讨论】:

  • 我刚刚找到了另一种解决方法。获取生成的 SQL 代码并在 SSMS 中执行。然后设置顺序。但是为什么有 2 个不同的结果而不是 3、4 或 5 个呢?
  • 我相信 SSMS 在获取数据时会使用一些唯一的行 ID/数据 ID 对数据进行内部排序,这就是为什么它能够为每个运行多次的 select 语句提供相同的行顺序。对于在编程范式中通过提供程序获取的数据,没有这样的内部排序。此外,订单数将取决于您获取的行数,如果您有大量记录,您会看到更高的订单不确定性。
【解决方案2】:

如前所述,排序永远不是确定性的,但尝试在您的 sql 查询或 Linq 查询中插入 orderby 子句,这是使其具有确定性的唯一方法。

事实上,让我们更深入地了解一下数据库的原因。 DB 将通过 i/o 从磁盘获取所有数据。数据存储在内部 sql server 结构中,如 pages、extents、segments(这些是 Oracle 数据块,我希望 sql server 有类似的东西)。现在,当查询被触发时,数据库将知道从中获取数据的所有不同位置,但这不是串行操作,它是一种并行获取,然后将不同的数据集组合起来以提供用户视图。现在我们知道在线程的情况下,谁先去谁先返回永远不能确定,这完全是线程的操作系统调度,希望进一步澄清。

OrderBy 子句将按照特定顺序处理获取的数据,因此总是会产生确定性的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多