C# SQL Server数据库的Queryable.OrderBy是否不稳定?

C# SQL Server数据库的Queryable.OrderBy是否不稳定?,c#,entity-framework,linq,linq-to-sql,iqueryable,C#,Entity Framework,Linq,Linq To Sql,Iqueryable,对于LINQ to对象是稳定的,但在Queryable上。OrderBy没有提到它是否稳定 我想这取决于提供者的实现。SQL Server是否不稳定?因为看起来是这样。我快速看了一下,但从那里看不清楚 我需要在执行其他操作之前订购一个集合,并且为了性能起见,我希望使用IQueryable,而不是IEnumerable // All the timestamps are the same and I am getting inconsistent // results by running it

对于LINQ to对象是稳定的,但在
Queryable上。OrderBy
没有提到它是否稳定

我想这取决于提供者的实现。SQL Server是否不稳定?因为看起来是这样。我快速看了一下,但从那里看不清楚

我需要在执行其他操作之前订购一个集合,并且为了性能起见,我希望使用
IQueryable
,而不是
IEnumerable

// All the timestamps are the same and I am getting inconsistent 
// results by running it multiple times, first few pages return the same results
var result = data.OrderBy(i => i.TimeStamp).Skip(start).Take(length);
但是如果我使用

var result = data.ToList().OrderBy(i => i.TimeStamp).Skip(start).Take(length);
它工作得很好,但我失去了从LINQ到SQL的性能提升。可查询的OrderBy/Skip/Take组合似乎会产生不一致的结果

生成的SQL代码在我看来很好:

SELECT 
...
FROM [dbo].[Table] AS [Extent1]
ORDER BY [Extent1].[TimeStamp] ASC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY 

在Linq到实体中,Linq查询被转换为SQL查询,所以OrderBy的Linq到对象实现并不重要。您应该查看ORDERBY的数据库实现。如果您使用的是MS SQL,您可以在文档中找到:

要在使用偏移和提取的查询请求之间获得稳定的结果,必须满足以下条件: (……)

  • ORDER BY子句包含保证唯一的列或列组合 因此,相同值的ORDER BY不能保证相同的顺序,因此限制它可能会提供不同的结果集。为了解决这个问题,您可以简单地通过一些具有唯一值的附加列进行排序,例如id。因此基本上您将有:

    var result = data
        .OrderBy(i => i.TimeStamp)
        .ThenBy(i => i.Id)
        .Skip(start)
        .Take(length);
    
    我认为“稳定”的意思是一致的。如果SQL查询中没有ORDER BY,则不能保证每次运行查询时数据的顺序。它将简单地以对服务器最有效的顺序返回所有数据。当您添加ORDER BY时,它将对该数据进行排序。由于在所有排序值相同的情况下对数据进行排序,因此不会对任何行进行重新排序,因此排序后的数据的顺序是您不期望的。如果需要特定的顺序,则需要添加辅助排序列,如ID


    最好不要假定从服务器返回的数据的顺序,除非您明确定义了该顺序。

    OrderBy被转换为SQL order by,因此它取决于数据库提供程序。@arekzyla数据库提供程序是MS SQL。您是否检查了执行的SQL查询?请参阅@MarcinJuraszek答案更新的漂亮答案
    ThenBy
    解决了这个问题。感谢您删除MS SQL文档中的行,很高兴知道这一点。