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子句来引用您的唯一属性来实现它,例如 答案很长: 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有两个选项: >创建新页面以分配新行. 假设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}] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |