Skip 和 Take 到底是如何工作的?

发布于 2024-11-04 05:49:56 字数 2737 浏览 1 评论 0 原文

我在 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]

I've got 2 queries in LINQ:

var users = (
    from u in dataContext.KUserNumbers
    select new {
        u.SubscriberAId,
        u.BNumber,
}).Take(10).ToList();

and the result is :

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

and second one:

users = (
    from u in dataContext.KUserNumbers
    select new {
        u.SubscriberAId,
        u.BNumber,
}).Skip(1).Take(10).ToList();

and I though that result would be sth like:

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

as I skip one row. but the result is completely different:

0 //+SDiKdXKBYAoicCWj7Bw
0 //03hO7doOCyhiopFJ82+w
0 //1iwyah26fjsJrQicb5pA
0 //3KaH4CBH2cI9ACwWf03Q
0 //4mtbXsQIg+QzcqTShPsw
0 //4O6INt73MsCRB6LV480A
0 //8zOGzTdDo7RMIoJLA0Mg
0 //CfYwcShDAgqbq3OCY8Nw
0 //cl71U4qnNfIrXwhsi5WQ
0 //CUIHrC0qHfS10AIihnKw

What is the reason for such a behaviour?

thanks for any help

EDIT:

If I Add orderBy subscriberAId after select statement I get:

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

updated queries:

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();

thats more or less how the query generated by linq looks like. What is funny when I use that query in management studio no result are returned. 0 rows :)

 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

予囚 2024-11-11 05:49:56

至于这些 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

梦行七里 2024-11-11 05:49:56

要回答“为什么”的问题,我建议检查生成的 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).

青衫负雪 2024-11-11 05:49:56

哈哈:)

添加

.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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文