Что в Linq to SQL эквивалентно TOP или LIMIT / OFFSET?

Как мне это сделать

Select top 10 Foo from MyTable

в Linq to SQL?


person Herb Caudill    schedule 10.10.2008    source источник


Ответы (13)


In 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 для более подробной информации.

person David Alpert    schedule 10.10.2008
comment
Это не работает в C #, здесь нет выражения take. Вам нужно использовать метод Take (). - person Adam Lassek; 10.10.2008
comment
Технически собеседник просил Linq to SQL, поэтому предположение VB является жизнеспособным. Тем не менее, Аласек, я сам разбираюсь в C # и предпочитаю ваш ответ. :-) - person David Alpert; 10.10.2008
comment
Ну, ваш пример был написан на C # LINQ, поэтому я указал на это. - person Adam Lassek; 10.10.2008
comment
спасибо, ALassek. Я не спал прошлой ночью, поэтому ценю уловку в моей грамматике. - person David Alpert; 10.10.2008
comment
2 проблемы: 1) это отлично работает в VB. в C # у вас есть метод Take. 2) дубль работает в клиенте, а не в базе данных, поэтому, если у вас большой набор результатов, вы в конечном итоге получите все это клиенту из базы данных! - person Yuki; 13.03.2011
comment
@Yuki, на самом деле метод LINQ .Take (10) преобразован в SQL SELECT TOP (10), поэтому дубль работает в клиенте НЕ истинно. - person Lessneek; 25.11.2011
comment
Примите во внимание, что ему несколько лет, но для тех, кто только начинает, стоит отметить, что .Take (x) должен появиться до того, как вы выполните .Select () или .ToList (), поскольку .Take (x) будет только быть включенным в сгенерированный SQL-запрос, если он был включен до перечисления результатов. Если он появится после этого, то это будет сделано после того, как будет перечислен набор результатов, и, следовательно, это будет простой старый оператор Linq! - person Bertie; 13.04.2012
comment
@Bertie ToList () да, Select () нет. Вы можете выполнить Select () перед Take (x) в C #, и предложение Top будет правильно сгенерировано. Select () - отложенная операция. - person Stephen Kennedy; 23.05.2012

Используйте метод 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.

person Adam Lassek    schedule 10.10.2008
comment
Небольшие различия в LINQ между C # и VB раздражают. Почему в C # нет выражения Take, такого как VB? Это похоже на оплошность. А отсутствие в VB анонимных подпрограмм делает лямбды гораздо менее полезными. - person Adam Lassek; 10.10.2008
comment
Именно то, что я искал +1 - person jasonco; 18.11.2009
comment
+1 Как раз то, что мне тоже было нужно. И FWIW, кажется, что только десять записей на самом деле упали. В противном случае мой SELECT вернул бы огромный объем данных, достаточный для выброса OutOfMemoryException после болезненной задержки. С Take (управляемое количество) без задержек, без исключения. - person Bob Kaufman; 21.07.2011
comment
VB теперь также имеет метод Take (). Мне пришлось использовать переменную для суммы, которую нужно взять, и выражение не работало, в то время как метод работал. - person Dave Johnson; 02.03.2016

Используйте метод Take(int n):

var q = query.Take(10);
person amcoder    schedule 10.10.2008

OP также упомянул смещение, поэтому, например, если вы хотите получить предметы от 30 до 60, вы должны:

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

Используйте метод «Пропустить» для смещения.
Используйте метод «Take» для ограничения.

person Inc33    schedule 16.10.2015

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

нет ? результаты могут быть разными.

person Yann    schedule 11.08.2010

Это хорошо работает в C #

var q = from m in MyTable.Take(10)
        select m.Foo
person spdrcr911    schedule 07.01.2010

Мне это нравится:

 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
                };
person Janei Vieira    schedule 26.01.2010
comment
Проблема с этим подходом заключается в том, что вы берете 4, а затем заказываете их, когда я подозреваю, что вы действительно хотите получить 4 лучших результата. Дубль нужно делать после заказа, см. Комментарий Янна. - person Russell Troywest; 22.09.2010

Вы бы использовали метод Take (N).

person FlySwat    schedule 10.10.2008

Произойдет ли дубль на клиенте или в базе данных, зависит от того, где вы применяете оператор дубля. Если вы примените его до перечисления запроса (т.е. перед тем, как использовать его в foreach или преобразовать в коллекцию), дубль приведет к отправке оператора SQL "top n" в базу данных. Вы можете увидеть это, если запустите профилировщик SQL. Если вы примените дубль после перечисления запроса, это произойдет на клиенте, поскольку LINQ должен будет получить данные из базы данных, чтобы вы могли их перечислить.

person user124368    schedule 22.11.2011

Взятие данных из базы данных без сортировки аналогично случайному извлечению

person Anton    schedule 04.06.2010
comment
Это, конечно, не случайно, хотя повторение результатов не гарантируется, но есть много раз, когда вы захотите сделать это, особенно при тестировании. - person Auspex; 07.11.2018

Мне пришлось использовать метод 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();
person Apollo SOFTWARE    schedule 09.05.2013

У меня это сработало:

var noticias = from n in db.Noticias.Take(6)
                       where n.Atv == 1
                       orderby n.DatHorLan descending
                       select n;
person Gladson Reis    schedule 01.10.2017
comment
Я только что отредактировал ваш пост, я перевел португальский текст на английский, потому что этот сайт только на английском языке (не относится к именам переменных, поэтому я их не менял). - person waka; 01.10.2017
comment
Извини ! Я не понимал, я думал, что попал в бразильский stackoverflow. Прости - person Gladson Reis; 02.10.2017

Для limit 1 используйте методы FirstOrDefault() или First().

Пример

var y = (from x in q select x).FirstOrDefault();

person Developer Marius Žilėnas    schedule 17.04.2019