O que o Linq to SQL equivale a TOP ou LIMIT / OFFSET?


Respostas:


146

No VB:

from m in MyTable
take 10
select m.Foo

Isso pressupõe que MyTable implementa IQueryable. Pode ser necessário acessá-lo por meio de um DataContext ou de outro provedor.

Ele também assume que Foo é uma coluna no MyTable que é mapeada para um nome de propriedade.

Consulte http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx para obter mais detalhes.


127
Isso não funciona em C #, não há expressão de aceitação. Você precisa usar o método Take ().
Adam Lassek 10/10/08

10
Tecnicamente, o questionador solicitou o Linq to SQL, então o VB é uma suposição viável. Dito isto, ALassek, eu sou um cara e prefiro sua resposta. :-)
David Alpert

3
Bem, seu exemplo foi escrito em C # LINQ e foi por isso que eu mencionei isso.
Adam Lassek 10/10/08

3
2 problemas: 1) isso funciona bem no VB. em c # você tem o método Take. 2) o take funciona no cliente, não no db; portanto, se você tiver um conjunto de resultados grande, acabaria recebendo tudo do db para o cliente!
Yuki

8
Perceba que isso tem alguns anos, mas para aqueles que estão chegando aqui, é importante notar que o ".Take (x)" deve aparecer antes de você fazer um ".Select ()" ou ".ToList ()", como o " .Take (x) "só será incluído no SQL gerado se for antes de você enumerar os resultados. Se aparecer depois disso, será feito assim que o conjunto de resultados tiver sido enumerado e, portanto, é uma instrução Linq antiga e simples!
22412 Bertie

248

Use o método Take :

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

No VB, o LINQ tem uma expressão take:

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

A partir da documentação:

Take<TSource>enumera sourcee produz elementos até que os countelementos tenham sido produzidos ou que sourcenão contenham mais elementos. Se countexceder o número de elementos em source, todos os elementos desource são retornados.


13
As pequenas diferenças no LINQ entre C # e VB são irritantes. Por que C # não tem uma expressão take como VB? Isso parece uma supervisão. E a falta de subs anônimos do VB torna as lambdas muito menos úteis.
Adam Lassek 10/10/08

Apenas o que eu estava procurando +1
jasonco 18/11/2009

1
+1 Exatamente o que eu precisava também. E FWIW, parece que apenas os dez discos realmente caem no cano. Caso contrário, meu SELECT retornaria uma quantidade enorme de dados, o suficiente para gerar uma OutOfMemoryException após um atraso doloroso. Com Take ( quantidade gerenciável ), sem atraso, sem exceção.
Bob Kaufman

O VB agora também possui um método Take (). Eu tive que usar uma variável para a quantidade a receber, e a expressão não funcionou, enquanto o método funcionou.
Dave Johnson

33

Use o Take(int n)método:

var q = query.Take(10);

25

O PO também mencionou a compensação, assim, por ex. se você gostaria de obter os itens de 30 a 60, você faria:

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

Use o método "Ignorar" para deslocamento.
Use o método "Take" para limitar.


13

@ Janei: meu primeiro comentário aqui é sobre sua amostra;)

Eu acho que se você gosta disso, você quer pegar 4 e aplicar o tipo nesses 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
                };

Diferente do que ordenar tbl_News inteiro por idNews descendente e depois levar 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);

não ? os resultados podem ser diferentes.


5

Isso funciona bem em c #

var q = from m in MyTable.Take(10)
        select m.Foo

4

Eu faço assim:

 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
O problema com essa abordagem é que você pega 4 e depois as ordena, quando eu suspeito que o que você realmente deseja é obter os 4 principais resultados. Você precisa fazer a tomada após o pedido, veja o comentário de Yanns.
Russell Troywest 22/09/10


3

Se a tomada acontece no cliente ou no banco de dados depende de onde você aplica o operador de tomada. Se você aplicá-lo antes de enumerar a consulta (ou seja, antes de usá-lo em um foreach ou convertê-lo em uma coleção), a tomada resultará no envio do operador "top n" SQL ao banco de dados. Você pode ver isso se executar o SQL Profiler. Se você aplicar a tomada após enumerar a consulta, ela ocorrerá no cliente, pois o LINQ terá que recuperar os dados do banco de dados para que você possa enumerá-la.


2

Obter dados do DataBase sem classificar é o mesmo que obter aleatoriamente


Certamente não é aleatório, embora os resultados não sejam garantidos para serem repetidos, mas há muitas vezes que você deseja fazer isso, principalmente nos testes.
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

Eu tive que usar o método Take (n), em seguida, transformar em lista, funcionou como um encanto:

    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

Dessa forma, funcionou para mim:

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

Acabei de editar seu post, traduzi o texto em português para inglês, porque este site é apenas em inglês (não se aplica a nomes de variáveis, é por isso que não os mudei).
waka

Desculpe ! Eu não percebi, pensei que estava no stackoverflow brasileiro. Desculpe
Gladson Reis

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.