【问题标题】:LINQ Skip(0) vs Skip(n), return inconsistent sort expressionLINQ Skip(0) vs Skip(n),返回不一致的排序表达式
【发布时间】:2010-03-18 06:00:14
【问题描述】:

当使用非 0 的起始索引调用 Skip() 方法时,该方法会自动追加附加列“除了”现有的 order-by 列。这些额外的排序列由不在排序表达式中的剩余列组成。 LINQ 很好地为我们自动处理这个问题,因为它为返回的数据提供了确定性排序;但是,当 0 传递给 Skip() 方法时(例如,在查询第一页时),该方法似乎已经过优化并且不会呈现上述附加的 order-by 列。这是有问题的,因为 Skip(0) 和 Skip(n) 之间的排序条件不一致。

另一位开发人员 Dave 也指出了同样的问题。 Quote: “Skip(0) 应该生成与 skip(n) 相同的行编号 sql...” 主题链接:http://www.eggheadcafe.com/conversation.aspx?messageid=32045245&threadid=32045239

有人遇到过类似的问题吗?幸运的是,我们查询的数据有一个标识列,因此我们想出的解决方法是始终将标识列附加到现有的排序表达式。我们很想听听其他创造性的方法或解决方案。


示例

下面的两个查询都从数据库中选择相同的列,并在列 RequestReceivedDate 上包含下降顺序。请注意,Skip(10) 生成的查询如何为剩余的列附加额外的排序,当存在具有相同 RequestReceivedDate 的记录时,这会导致不同的数据排序。附加这些额外排序的想法很棒;但是,该库应该为 Skip(0) 实现相同的逻辑,因此 Skip(0) 和 Skip(n) 将以相同的顺序返回数据。

[由 Skip(0).Take(10) 生成的查询]

SELECT TOP (10) [t31].[PersonId], [t31].[value] AS [RequestReceivedDate2], ....
FROM (
    SELECT [t0].[PersonId], (
        SELECT MAX([t8].[RequestReceivedDate])
        FROM [dbo].[EnrollRequest] AS [t8]
        WHERE EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[DomainAccount] AS [t9]
            WHERE ([t9].[DomainAccountId] = [t8].[DomainAccountId]) AND ([t9].[PersonId] = ([t0].[PersonId]))
            )
        ) AS [value], ... 
    ) AS [t31]
ORDER BY [t31].[value] DESC

[由 Skip(10).Take(10) 生成的查询]

SELECT [t32].[PersonId], [t32].[value] AS [RequestReceivedDate2], ...
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t31].[value] DESC) AS [ROW_NUMBER], [t31].[PersonId], [t31].[value], [t31].[FullAccountName], [t31].[LastName], ...
    FROM (
        SELECT [t0].[PersonId], (
            SELECT MAX([t8].[RequestReceivedDate])
            FROM [dbo].[EnrollRequest] AS [t8]
            WHERE EXISTS(
                SELECT NULL AS [EMPTY]
                FROM [dbo].[DomainAccount] AS [t9]
                WHERE ([t9].[DomainAccountId] = [t8].[DomainAccountId]) AND ([t9].[PersonId] = ([t0].[PersonId]))
                )
            ) AS [value], ...
    ) AS [t32]
WHERE [t32].[ROW_NUMBER] BETWEEN @p21 + 1 AND @p21 + @p22
ORDER BY [t32].[ROW_NUMBER]

【问题讨论】:

  • 能否包含 LINQ 查询,您的 Skip 可能在错误的位置。

标签: linq


【解决方案1】:

显然,this issue is fixed in LINQ to SQL in .NET 4.0:

Skip(0) 不再阻止预加载

【讨论】:

    【解决方案2】:

    从链接来看,这看起来像是一个 LINQ to SQL 问题。并且有一个无序的 SELECT ,其中 LINQ 在跳过后返回不同的结果。

    但是,您不能依赖 SQL 返回其行的顺序,除非您指定 order by 子句。

    你能提供一个完整的样本吗?

    【讨论】:

    • 您好山姆,谢谢您的回复。我已经为您的评论提供了一个示例。谢谢 - 马丁
    猜你喜欢
    • 1970-01-01
    • 2015-04-08
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多