LINQ排序依据。它是否总是返回相同的排序列表? [英] LINQ OrderBy. Does it always return the same ordered list?

查看:181
本文介绍了LINQ排序依据。它是否总是返回相同的排序列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是想了一个简单的排序依据的语句。

I was trying out a simple OrderBy statement.

目标数据命令是类似如下:

The target data to order is something like below:

[
  {"id":40, "description":"aaa", "rate":1},
  {"id":1, "description":"bbb", "rate":1},
  {"id":4, "description":"ccc", "rate":2},
  {"id":19, "description":"aaa", "rate":1}, ... 
]

然后,我通过率产权制度的项目。

Then I order items by the rate property.

奇怪的是,如果我'秩序'他们,这跳过一些项目的特定数据偏移,然后采取只部分。

The odd thing is that if I 'order' them, it 'skips' some items by a given offset and then 'take' only portion of the data.

例如,

var result = items.OrderBy(i => i.rate);
var result = result.Skip(2);
var result = result.Take(2);

结果看起来不错的大部分,但边缘情况项不返回的。

The result looks fine for the most of it, but the 'edge case' item is not returned at all.

例如,

如果第一个结果回来为

    [{"id":40, "description":"aaa", "rate":1}, {"id":1, "description":"bbb", "rate":1}]

第二个结果回来像

the second result comes back like

    [{"id":1, "description":"bbb", "rate":1}, {"id":4, "description":"ccc", "rate":2}]

项目编号:19没有得到回报与第二个查询电话。相反,项目ID:1。返回两次

Item "id: 19" has not been returned with the second query call. Instead item "id: 1" has returned twice.

我的猜测是,SQL排序依据语句不按给定的属性产生同样的有序列表,每一次*排序依据订单,但在一组的准确顺序共享相同的属性可以改变*。

My guess is that the SQL OrderBy statement doesn't produce the same ordered list every single time * OrderBy orders by a given property, but the exact order within a group that shares the same property can change *.

什么是引擎盖下的确切机制?

What is the exact mechanism under the hood?

推荐答案

简短的回答: LINQ到对象使用一个稳定的排序算法,所以我们可以说,这是确定的,和LINQ to SQL依赖对数据库执行的ORDER BY也就是通常不确定的。

Short answer: LINQ to Objects uses a stable sort algorithm, so we can say that it is deterministic, and LINQ to SQL depends on the database implementation of Order By that is usually nondeterministic.

一个确定性排序算法是一个始终在不同的运行相同的行为。

A deterministic sort algorithm is one that have always the same behavior on different runs.

在你的例子,你在你的OrderBy子句重复。对于保障和predicted排序,顺序条款或订单条款的组合中的一个必须的唯一的。

In you example, you have duplicates in your OrderBy clause. For a guaranteed and predicted sort, one of the order clauses or the combination of order clauses must be unique.

在LINQ中,你可以通过添加另一个排序依据条款是指你的独特性,就像在
实现它 items.OrderBy(I => i.Rate).ThenBy(I => i.ID)。

In LINQ, you can achieve it by adding another OrderBy clause to refer your unique property, like in
items.OrderBy(i => i.Rate).ThenBy(i => i.ID).

的回答:

LINQ到对象使用一个稳定的排序,如记录在此链接: / A>。

LINQ to Objects uses a stable sort, as documented in this link: MSDN.

在LINQ到SQL,这取决于底层数据库的排序算法,它通常是一种不稳定的排序,像MS SQL Server中(的 MSDN )。

In LINQ to SQL, it depends on the sort algorithm of the underlying database and it is usually an unstable sort, like in MS SQL Server (MSDN).

在一个稳定的排序中,如果两个元件的键是相等的,该元素的顺序是preserved。相反,不稳定的排序不preserve具有相同键元件的顺序

In a stable sort, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key.

所以,对LINQ到SQL,排序通常是不确定的,因为在关系数据库管理系统(关系数据库管理系统,如MS SQL Server)的可直接使用不稳定的排序算法与随机支点选择或随机性可以与哪个行的数据库首先发生,可访问该文件系统有关。

So, for LINQ to SQL, the sorting is usually nondeterministic because the RDMS (Relational Database Management System, like MS SQL Server) may directly use a unstable sort algorithm with a random pivot selection or the randomness can be related with which row the database happens to access first in the file system.

例如,假设在文件系统中的页的大小可容纳4行

For example, imagine that the size of a page in the file system can hold up to 4 rows.

如果您将以下资料页面将以饱满:

The page will be full if you insert the following data:

     Page 1
| Name | Value |
|------|-------|
|   A  |   1   |
|   B  |   2   |
|   C  |   3   |
|   D  |   4   |


如果你需要插入新行的关系数据库管理系统有两种选择:


If you need to insert a new row, the RDMS has two options:

  1. 创建一个新的页面来分配新行。
  2. 拆分当前页面的两页。因此,第一个页面将保持名称的 A B 并在第二页将持有的 C ð
  1. Create a new page to allocate the new row.
  2. Split the current page in two pages. So the first page will hold the Names A and B and the second page will hold C and D.

假设关系数据库管理系统选择选项1(以减少索引碎片)。如果插入了名称的新行的 C 和值 9 后,您将获得:

Suppose that the RDMS chooses option 1 (to reduce index fragmentation). If you insert a new row with Name C and Value 9, you will get:

     Page 1              Page 2
| Name | Value |    | Name | Value |
|------|-------|    |------|-------|
|   A  |   1   |    |   C  |   9   |
|   B  |   2   |    |      |       |
|   C  |   3   |    |      |       |
|   D  |   4   |    |      |       |


也许的,在列的排序依据子句中的名称将返回如下:


Probably, the OrderBy clause in column Name will return the following:

| Name | Value |
|------|-------|
|   A  |   1   |
|   B  |   2   |
|   C  |   3   |
|   C  |   9   | -- Value 9 appears after because it was at another page
|   D  |   4   |



现在,假设关系数据库管理系统选择选项2(增加存储系统的插入性能与许多锭)。如果插入了名称的新行的 C 和值 9 后,您将获得:

Now, suppose that the RDMS chooses option 2 (to increase the insert performance in a storage system with many spindles). If you insert a new row with Name C and Value 9, you will get:

     Page 1              Page 2
| Name | Value |    | Name | Value |
|------|-------|    |------|-------|
|   A  |   1   |    |   C  |   3   |
|   B  |   2   |    |   D  |   4   |
|   C  |   9   |    |      |       |
|      |       |    |      |       |


也许的,在列的排序依据子句中的名称将返回如下:


Probably, the OrderBy clause in column Name will return the following:

| Name | Value |
|------|-------|
|   A  |   1   |
|   B  |   2   |
|   C  |   9   |  -- Value 9 appears before because it was at the first page
|   C  |   3   | 
|   D  |   4   |


关于你提到的例子:


Regarding your example:

我相信你打错东西在你的问题,因为你已经使用 items.OrderBy(I => i.rate).Skip(2)。取(2); 键,第一个结果没有显示出一排率= 2 。这是不可能的,因为将忽略前两行,他们有率= 1 ,让你的输出必须显示出与该行率= 2

I believe that you have mistyped something in your question, because you have used items.OrderBy(i => i.rate).Skip(2).Take(2); and the first result do not show a row with Rate = 2. This is not possible since the Skip will ignore the first two rows and they have Rate = 1, so your output must show the row with Rate = 2.

您已经标记数据库你的问题,所以我相信,你正在使用LINQ到SQL。在这种情况下,结果是不确定的,你可以得到如下:

You've tagged your question with database, so I believe that you are using LINQ to SQL. In this case, results can be nondeterministic and you could get the following:

结果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)。取(2); 那么唯一可能的结果将是:

If you had used items.OrderBy(i => i.rate).ThenBy(i => i.ID).Skip(2).Take(2); then the only possible result would be:

[{"id":40, "description":"aaa", "rate":1},
 {"id":4, "description":"ccc", "rate":2}]

这篇关于LINQ排序依据。它是否总是返回相同的排序列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆