简短回答: LINQ to Objects使用稳定排序算法,因此我们可以说它是确定性的,而LINQ to SQL取决于通常是不确定性的Order By数据库实现。
确定性排序算法在不同运行时始终具有相同的行为。
在您的示例中,OrderBy子句中存在重复项。为了获得保证和预测可能的排序,必须使其中一个排序子句或排序子句的组合是唯一的。
在LINQ中,您可以通过添加另一个OrderBy子句来引用唯一属性来实现,例如
items.OrderBy(i => i.Rate).ThenBy(i => i.ID)
。
长回答:
LINQ to Objects使用稳定排序,如此链接中所述:MSDN。
在LINQ to SQL中,它取决于底层数据库的排序算法,并且通常是不稳定的,例如在MS SQL Server中 (MSDN)。
在稳定排序中,如果两个元素的键相等,则元素的顺序将被保留。相反,不稳定排序不保留具有相同键的元素的顺序。
因此,对于LINQ to SQL,排序通常是不确定性的,因为关系数据库管理系统(例如MS SQL Server)可以直接使用带有随机中心选择的不稳定排序算法,或者随机性可能与数据库首先访问文件系统的哪个行相关联。
例如,想象一下,文件系统中的页面大小可以容纳最多4行。
如果您插入以下数据,则该页面将已满:
Page 1
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 3 |
| D | 4 |
如果需要插入新行,则关系数据库管理系统有两个选项:
- 创建一个新页面以分配新行。
- 将当前页面分成两个页面。因此,第一页将保存名称为A和B的内容,而第二页将保存C和D。
假设RDMS选择选项1(以减少索引碎片),如果插入名称为C和值为9的新行,则会出现:
Page 1 Page 2
| Name | Value | | Name | Value |
|------|-------| |------|-------|
| A | 1 | | C | 9 |
| B | 2 | | | |
| C | 3 | | | |
| D | 4 | | | |
很可能,按照 Name 列进行排序将返回以下结果:
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 3 |
| C | 9 | -- Value 9 appears after because it was at another page
| D | 4 |
现在,假设 RDMS 选择选项2(为具有多个主轴的存储系统增加插入性能)。 如果您插入名称为 C 和值为 9 的新行,则会得到:
Page 1 Page 2
| Name | Value | | Name | Value |
|------|-------| |------|-------|
| A | 1 | | C | 3 |
| B | 2 | | D | 4 |
| C | 9 | | | |
| | | | | |
可能,按照 Name 列的 OrderBy 条件将会返回以下结果:
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 9 | -- Value 9 appears before because it was at the first page
| C | 3 |
| D | 4 |
关于您的例子:
我相信您在问题中打错了一些内容,因为您使用了
items.OrderBy(i => i.rate).Skip(2).Take(2);
,但第一个结果没有显示一个具有
Rate = 2
的行。这是不可能的,因为
Skip
将忽略前两行,它们具有
Rate = 1
,所以您的输出必须显示
Rate = 2
的行。
您已经用
database
标记了您的问题,因此我认为您正在使用LINQ to SQL。在这种情况下,结果可能是不确定性的,您可能会得到以下结果:
结果1:
[{"id":40, "description":"aaa", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
结果2:
[{"id":1, "description":"bbb", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
如果你使用了 items.OrderBy(i => i.rate).ThenBy(i => i.ID).Skip(2).Take(2);
,那么唯一可能的结果是:
[{"id":40, "description":"aaa", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
order by rate, description
,那么它将按rate
排序,然后在rate
值重复的情况下按description
排序。仍然可能存在多行具有相等的rate
和description
值,它们的顺序将保持未指定状态。id
通常用作解决决斗者以确保稳定的顺序:order by rate, description, id
。 - HABO