Що таке Linq - SQL еквівалентно TOP або LIMIT / OFFSET?


Відповіді:


146

В VB:

from m in MyTable
take 10
select m.Foo

Це передбачає, що MyTable реалізує IQueryable. Можливо, вам доведеться отримати доступ до цього через DataContext або інший провайдер.

Він також передбачає, що Foo - це стовпець у MyTable, який отримує відображення до імені властивості.

Детальніше див. На веб-сторінці http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx .


127
Це не працює в C #, немає експресії. Потрібно використовувати метод Take ().
Адам Лассек

10
Технічно запитувач запитував Linq в SQL, тому VB є припустимим припущенням. Тим не менш, ALassek, я сам # єдний хлопець і вважаю за краще вашу відповідь. :-)
Девід Альперт

3
Ну, ви, наприклад, були написані на C # LINQ, саме тому я це вказав.
Адам Лассек

3
2 проблеми: 1) це добре працює у VB. у C # у вас є метод Take. 2) Take працює в клієнті, а не в db, тому якщо у вас великий набір результатів, ви в кінцевому підсумку отримаєте все це для клієнта від db!
Юкі

8
Оцініть це за кілька років, але для тих, хто тільки потрапляє сюди, варто зазначити, що ".Take (x)" повинен з’явитися перед тим, як зробити ".Select ()" або ".ToList ()", як " .Take (x) "буде включений до генерованого SQL лише тоді, коли він буде перерахований за результатами. Якщо він з'явиться після цього, то це буде зроблено, коли набір результатів буде перерахований і тому є простим старим заявою Linq!
Берті

248

Використовуйте метод Take :

var foo = (from t in MyTable
           select t.Foo).Take(10);

У VB LINQ має вираз take:

Dim foo = From t in MyTable _
          Take 10 _
          Select t.Foo

З документації:

Take<TSource>перераховує sourceта дає елементи до тих пір, поки countелементи не будуть виведені або sourceне містять більше елементів. Якщо countкількість елементів у них перевищує source, всі елементи sourceповертаються.


13
Невеликі відмінності в LINQ між C # і VB дратують. Чому C # не має експресії на зразок VB? Це здається недоглядом. А відсутність анонімного абонементу VB робить лямбдаси набагато менш корисними.
Адам Лассек

Якраз те, що я шукав +1
jasonco

1
+1 Просто те, що мені було потрібно. І FWIW, здається, що лише десять записів насправді спускаються. Мій SELECT інакше поверне величезну кількість даних, достатню для того, щоб викинути OutOfMemoryException після болісної затримки. З Take ( керована кількість ), без затримки, не виняток.
Боб Кауфман

Тепер VB також має метод Take (). Я повинен був використовувати змінну для суми, яку потрібно взяти, і вираз не працював, тоді як метод це робив.
Дейв Джонсон


25

ОП також фактично згадувало про компенсацію, так, наприклад, якщо ви хочете отримати товари від 30 до 60, ви зробите:

var foo = (From t In MyTable
       Select t.Foo).Skip(30).Take(30);

Для компенсації використовуйте метод «Пропустити».
Використовуйте метод "Прийняти" для обмеження.


13

@Janei: мій перший коментар тут стосується вашого зразка;)

Я думаю, якщо ви робите так, ви хочете взяти 4, а потім застосувати сортування на ці 4.

var dados =  from d in dc.tbl_News.Take(4) 
                orderby d.idNews descending
                select new 
                {
                    d.idNews,
                    d.titleNews,
                    d.textNews,
                    d.dateNews,
                    d.imgNewsThumb
                };

Відмінна від сортування цілих tbl_News за idNews за спаданням та взяттям 4

var dados =  (from d in dc.tbl_News
                orderby d.idNews descending
                select new 
                {
                    d.idNews,
                    d.titleNews,
                    d.textNews,
                    d.dateNews,
                    d.imgNewsThumb
                }).Take(4);

немає ? результати можуть бути різними.



4

Мені так подобається:

 var dados =  from d in dc.tbl_News.Take(4) 
                orderby d.idNews descending

                select new 
                {
                    d.idNews,
                    d.titleNews,
                    d.textNews,
                    d.dateNews,
                    d.imgNewsThumb
                };

7
Проблема такого підходу полягає в тому, що ви візьмете 4, а потім замовите їх, коли я підозрюю, що ви насправді хочете - отримати найкращі 4 результати. Вам потрібно зробити прийом після замовлення, дивіться коментар Янса.
Рассел Troywest


3

Незалежно від того, чи відбуватиметься у клієнта або в db, залежить від того, де ви застосуєте оператора take. Якщо ви застосуєте його перед тим, як перерахувати запит (тобто перед тим, як використовувати його в foreach або перетворити його в колекцію), взяття результату призведе до того, що "n n" SQL-оператор буде відправлений на db. Це можна побачити, якщо ви запускаєте SQL-профілер. Якщо ви застосуєте take після перерахування запиту, це станеться з клієнтом, оскільки LINQ повинен був отримати дані з бази даних, щоб ви перерахували його


2

Отримання даних DataBase без сортування - це те саме, що і випадкове взяття


Це, звичайно, не випадково, хоча результати не є гарантовано повторюваними, але ви хочете зробити це багато разів, особливо під час тестування.
Auspex

2
Array oList = ((from m in dc.Reviews
                           join n in dc.Users on m.authorID equals n.userID
                           orderby m.createdDate descending
                           where m.foodID == _id                      
                           select new
                           {
                               authorID = m.authorID,
                               createdDate = m.createdDate,
                               review = m.review1,
                               author = n.username,
                               profileImgUrl = n.profileImgUrl
                           }).Take(2)).ToArray();

0

Мені довелося скористатися методом Take (n), потім перетворитись на список, Працював як шарм:

    var listTest = (from x in table1
                     join y in table2
                     on x.field1 equals y.field1
                     orderby x.id descending
                     select new tempList()
                     {
                         field1 = y.field1,
                         active = x.active
                     }).Take(10).ToList();

0

Таким чином, це працювало для мене:

var noticias = from n in db.Noticias.Take(6)
                       where n.Atv == 1
                       orderby n.DatHorLan descending
                       select n;

Я щойно відредагував ваше повідомлення, я переклав португальський текст англійською мовою, тому що цей сайт є лише англійською мовою (не стосується імен змінних, тому я їх не змінив).
waka

Вибачте! Я не усвідомлював, думав, що перебуваю в бразильському стаковерсі. Вибачте
Гладсон Рейс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.