开发者

how does skip and take really work?

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 (ORD开发者_运维知识库ER 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]


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


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


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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜