sql – LINQ OrderBy.它总是返回相同的有序列表吗?

前端之家收集整理的这篇文章主要介绍了sql – LINQ OrderBy.它总是返回相同的有序列表吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试一个简单的OrderBy语句.

要订购的目标数据如下所示:

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

然后我按照房价订购商品.

奇怪的是,如果我’命令’它们,它会’跳过’某个项目的给定偏移量,然后“仅”获取部分数据.

例如,

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

结果看起来很好,但是“边缘情况”项目根本不会返回.

例如,

如果第一个结果回来了

[{"id":40,"rate":1}]

第二个结果回来了

[{"id":1,"rate":2}]

第二次查询调用尚未返回项“id:19”.相反,项目“id:1”已返回两次.

我的猜测是,sql OrderBy语句不会在给定属性的每次OrderBy命令时产生相同的有序列表,但是共享相同属性的组中的确切顺序可能会发生变化.

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

解决方法

简短回答: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,排序通常是不确定的,因为RDMS(关系数据库管理系统,如MS sql Server)可能直接使用带有随机数据透视选择的不稳定排序算法,或者随机性可能与数据库发生的哪一行有关首先在文件系统中访问.

例如,假设文件系统中页面的大小最多可容纳4行.

如果插入以下数据,页面将填满:

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

如果需要插入新行,RDMS有两个选项:

>创建新页面以分配新行.
>将当前页面拆分为两页.因此第一页将保留名称A和B,第二页将保存C和D.

假设RDMS选择选项1(以减少索引碎片).如果您插入名为C和Value 9的新行,您将获得:

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

可能,列Name中的OrderBy子句将返回以下内容

| 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和Value 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的行.

您已使用数据库标记了您的问题,因此我相信您使用的是LINQ to sql.在这种情况下,结果可能是不确定的,您可以获得以下结果:

结果1:

[{"id":40,"rate":2}]

结果2:

[{"id":1,"rate":2}]

如果你曾经使用过items.OrderBy(i => i.rate).ThenBy(i => i.ID).Skip(2).Take(2);那么唯一可能的结果是:

[{"id":40,"rate":2}]
原文链接:https://www.f2er.com/mssql/83262.html

猜你在找的MsSQL相关文章