Skip 和 Take 到底是如何工作的?
我在 LINQ: 中有 2 个查询,
var users = (
from u in dataContext.KUserNumbers
select new {
u.SubscriberAId,
u.BNumber,
}).Take(10).ToList();
结果是 :
341767 HjbZ8UUO3Ob0ubTk5q2GXg
3451645 9PJwin/OEIxY5G1O3Wm0Ow
645560 3Ps6KvC2haleNT0cm+0eeA
5360374 ktJuCU861efptHPtSnYtIQ
5352388 SJKJVqeOMpW3yAFLJeeVaQ
3027301 0N2+LgMCpOKvNLkAjBPicQ
24697284 XhmdWliLn0U4UI+jPeeVDw
23555123 ox2sYcehRXKJW0y1ppTGRg
28920232 G3/EkrSpTOPjGHme8itApw
3032925 j/LQt0BtMohrLG5wqWQW0g
,第二个查询是 :
users = (
from u in dataContext.KUserNumbers
select new {
u.SubscriberAId,
u.BNumber,
}).Skip(1).Take(10).ToList();
,我认为结果会是这样的:
3451645 9PJwin/OEIxY5G1O3Wm0Ow
645560 3Ps6KvC2haleNT0cm+0eeA
5360374 ktJuCU861efptHPtSnYtIQ
5352388 SJKJVqeOMpW3yAFLJeeVaQ
3027301 0N2+LgMCpOKvNLkAjBPicQ
24697284 XhmdWliLn0U4UI+jPeeVDw
23555123 ox2sYcehRXKJW0y1ppTGRg
28920232 G3/EkrSpTOPjGHme8itApw
3032925 j/LQt0BtMohrLG5wqWQW0g
additional one row
因为我跳过一行。但结果却完全不同:
0 //+SDiKdXKBYAoicCWj7Bw
0 //03hO7doOCyhiopFJ82+w
0 //1iwyah26fjsJrQicb5pA
0 //3KaH4CBH2cI9ACwWf03Q
0 //4mtbXsQIg+QzcqTShPsw
0 //4O6INt73MsCRB6LV480A
0 //8zOGzTdDo7RMIoJLA0Mg
0 //CfYwcShDAgqbq3OCY8Nw
0 //cl71U4qnNfIrXwhsi5WQ
0 //CUIHrC0qHfS10AIihnKw
这种行为的原因是什么?
感谢您的任何帮助
编辑:
如果我在 select 语句后添加 orderBySubscriberAId 我得到:
0 Pj5U5pJzrZn4e2Wr4r0H6Q
0 iVu3fam6j3TRbMGdngTtuw
0 i5STtn65LZE7tJfMUPkhug
0 DyhCFKAp5oe0mm5T2Glgpw
0 GaI7ltFJkVeXjMRXShQyLg
0 uneqHdkaBBMeY4Eir7ySZw
0 BAVlunfU4tak4PFY2OxeNg
0 rd4EDeeMUJ/zKDs1IX+Y5w
0 71H3NKg3wLr3/3Iq0HDcEw
0 EeSuYD+003J0g0/ysVteHA
0 nLGfZFEtGnQeJ4I6P8Jy3w
0 B2i5pv26ZzCgi3DISay+Ag
0 57foBJuQV/+6czziRPNQ1A
0 EBBzbvtSDk+T34m+x3F96A
0 BRWpIbeMGQdh/3MANk4AXw
0 0MiqFyqiPpKarJoj/99uMw
0 AdZ6RAHLY86Qe0OG8aZfkw
0 ISSsqPVacX7RQtEwLEWTvw
0 1bPIdr1yDzg8e00gkPmXew
0 k7flvu9G8F8ACWY3zDmSuw
更新的查询:
var users = (
from u in dataContext.KUserNumbers
select new {
u.SubscriberAId,
u.BNumber,
}).OrderBy(u => u.SubscriberAId).Take(10).ToList();
sers = (
from u in dataContext.KUserNumbers
select new {
u.SubscriberAId,
u.BNumber,
}).OrderBy(u => u.SubscriberAId).Skip(1).Take(10).ToList();
这或多或少是由 linq 生成的查询的样子。有趣的是,当我在管理工作室中使用该查询时,没有返回结果。 0 行:)
SELECT [SubscriberAId], [BNumber]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [SubscriberAId]) AS [ROW_NUMBER], [SubscriberAId], [BNumber]
FROM [dbo].[KUserNumber]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN 1 + 1 AND 1 + 10
ORDER BY [t1].[ROW_NUMBER]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
至于这些 linq 方法如何“真正工作”,我找到的用于这种理解的最佳资源是 Jon Skeet 的 Reimplementing Linq to Objects,for Skip/Take:
https://msmvps.com/blogs/jon_skeet/archive/2011/01/02/reimplementing-linq-to-objects-part-23-take-skip-takewhile-skipwhile.aspx
至于为什么您运行的两个 linq 查询会产生这种效果,我只能预计 dataContext.KUserNumbers 不会按特定顺序枚举?尝试在两个查询中的 select 语句之后引入 OrderBy,看看是否会给出更明显的结果。
如果您喜欢这篇文章,可以在这里找到整个系列:
http://edulinq.googlecode .com/hg/posts/index.html
当您专门使用 linq2sql 时,另一个很好的调试资源是调试可视化工具,它允许您查看将传递到数据库层的查询。这通常会煽动数据库请求任何异常的内容:
http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx
As for how these linq methods "really work" the best resource I have found for such understanding is Jon Skeet's Reimplementing Linq to Objects, for Skip/Take:
https://msmvps.com/blogs/jon_skeet/archive/2011/01/02/reimplementing-linq-to-objects-part-23-take-skip-takewhile-skipwhile.aspx
As for why the two linq queries you are running are having that effect, I can only anticipate that dataContext.KUserNumbers does not enumerate in a specific order? Try introducing an OrderBy after the select statements in both queries to see if it gives a more obvious result.
In case you enjoy the article you can find the whole series here:
http://edulinq.googlecode.com/hg/posts/index.html
Another good resource for debugging when you are specifically using linq2sql is the Debug Visualizer which will allow you to see the queries which will be passed on to the database layer. This often give an incite into anything unusual being requested from the db:
http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx
要回答“为什么”的问题,我建议检查生成的 SQL 像这样。这将告诉您如何解释 Skip。
也就是说,如果 Skip 计数始终是一个相对较小的数字,一个简单实用的解决方案是
Take(N+k).ToList().Skip(k)
。To answer the question of 'why', I recommend inspecting the generated SQL like this. This will tell you how the Skip is being interpreted.
That said, if the Skip count is always a relatively small number, a simple practical solution is to
Take(N+k).ToList().Skip(k)
.哈哈:)
添加
.ThenBy(u=>u.BNumber) 解决了问题。这意味着您永远无法确定结果是什么,特别是如果表很大(可能在 sql server 中位于多个页面上)。
您需要提供良好的排序(尝试使行不同)
haha :)
adding
.ThenBy(u=>u.BNumber) solved the problem. It means that You can never be sure what is the result especially if the table is big (problably if is on more than one page in sql server).
You need to provide good sorting (try to make rows distinct)