как пропустить и взять действительно работает? - PullRequest
2 голосов
/ 02 мая 2011

У меня есть 2 запроса в LINQ:

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

В чем причина такого поведения?

спасибо за любую помощь

EDIT:

Если я добавлю orderBy subscriberAId после оператора select, я получу:

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]

Ответы [ 3 ]

3 голосов
/ 02 мая 2011

Что касается того, как эти методы linq «действительно работают», лучшим ресурсом, который я нашел для такого понимания, является «Переопределение Linq для объектов» Джона Скита для 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 не будет перечисляться в определенном порядке?Попробуйте ввести OrderBy после операторов select в обоих запросах, чтобы увидеть, дает ли он более очевидный результат.

Если вам понравилась статья, вы можете найти всю серию здесь:

http://edulinq.googlecode.com/hg/posts/index.html

Другим хорошим ресурсом для отладки, когда вы специально используете linq2sql, является визуализатор отладки, который позволит вам увидеть запросы, которые будут переданы на уровень базы данных.Это часто приводит к чему-то необычному, запрашиваемому у БД:

http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx

1 голос
/ 02 мая 2011

хаха:)

добавление

.ThenBy (u => u.BNumber) решил проблему. Это означает, что Вы никогда не можете быть уверены, каков будет результат, особенно если таблица большая (вероятно, если она находится на нескольких страницах в SQL Server).

Вам нужно обеспечить хорошую сортировку (попытайтесь выделить строки)

1 голос
/ 02 мая 2011

Чтобы ответить на вопрос «почему», я рекомендую проверить сгенерированный SQL следующим образом .Это скажет вам, как интерпретируется Пропуск.

Тем не менее, если число Пропусков всегда относительно мало, простое практическое решение - Take(N+k).ToList().Skip(k).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...