【发布时间】: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