¿Cuál es el equivalente de Linq a SQL a TOP o LIMIT / OFFSET?


Respuestas:


146

En VB:

from m in MyTable
take 10
select m.Foo

Esto supone que MyTable implementa IQueryable. Puede que tenga que acceder a través de un DataContext u otro proveedor.

También supone que Foo es una columna en MyTable que se asigna a un nombre de propiedad.

Consulte http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx para obtener más detalles.


127
Eso no funciona en C #, no hay expresión de toma. Necesita usar el método Take ().
Adam Lassek

10
Técnicamente, el interlocutor pidió Linq a SQL, por lo que VB es una suposición viable. Dicho esto, ALassek, yo mismo soy un chico # # y prefiero tu respuesta. :-)
David Alpert

3
Bueno, su ejemplo fue escrito en C # LINQ, por eso lo señalé.
Adam Lassek

3
2 problemas: 1) esto funciona bien en VB. en C # tienes el método Take. 2) la toma funciona en el cliente, no en db, por lo que si tiene un conjunto de resultados grande, ¡terminará llevándolo todo al cliente desde el db!
Yuki

8
Aprecio que esto tiene algunos años, pero para aquellos que acaban de llegar, vale la pena señalar que ".Take (x)" debe aparecer antes de hacer un ".Select ()" o ".ToList ()", como el " .Take (x) "solo se incluirá en el SQL generado si es antes de enumerar los resultados. Si aparece después de esto, se realizará una vez que se haya enumerado el conjunto de resultados y, por lo tanto, ¡es una simple y antigua declaración de Linq!
Bertie

248

Utiliza el método Take :

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

En VB LINQ tiene una expresión take:

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

De la documentación:

Take<TSource>enumera sourcey produce elementos hasta que los countelementos hayan sido cedidos o sourceno contengan más elementos. Si countexcede el número de elementos source, sourcese devuelven todos los elementos de .


13
Las pequeñas diferencias en LINQ entre C # y VB son molestas. ¿Por qué C # no tiene una expresión take como VB? Eso parece un descuido. Y la falta de Subs anónimos de VB hace que las lambdas sean mucho menos útiles.
Adam Lassek

Justo lo que estaba buscando +1
jasonco

1
+1 Justo lo que necesitaba, también. Y FWIW, parece que solo los diez registros realmente caen en picado. De lo contrario, mi SELECT devolvería una enorme cantidad de datos, suficiente para lanzar una OutOfMemoryException después de un retraso doloroso. Con Take ( cantidad manejable ), sin demora, sin excepción.
Bob Kaufman

VB ahora también tiene un método Take (). Tuve que usar una variable para la cantidad a tomar, y la expresión no funcionó, mientras que el método sí.
Dave Johnson


25

El OP también mencionó el desplazamiento, así que por ej. si desea obtener los artículos del 30 al 60, haría:

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

Use el método "Saltar" para el desplazamiento.
Use el método "Take" para el límite.


13

@Janei: mi primer comentario aquí es sobre su muestra;)

Creo que si te gusta esto, quieres tomar 4 y luego aplicar el tipo en estos 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 a ordenar todo tbl_News por idNews descendiendo y luego tomando 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);

No ? Los resultados pueden ser diferentes.


5

Esto funciona bien en C #

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

4

Me gusta esto:

 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
                };

77
El problema con este enfoque es que tomará 4 y luego los ordenará, cuando sospecho que lo que realmente quiere es obtener los 4 mejores resultados. Debe hacer la toma después del pedido, vea el comentario de Yanns.
Russell Troywest


3

Si la toma ocurre en el cliente o en la base de datos depende de dónde aplique el operador de toma. Si lo aplica antes de enumerar la consulta (es decir, antes de usarla en un foreach o convertirla en una colección), la toma dará como resultado que el operador SQL "n superior" se envíe a la base de datos. Puede ver esto si ejecuta el generador de perfiles SQL. Si aplica la toma después de enumerar la consulta, sucederá en el cliente, ya que LINQ habrá tenido que recuperar los datos de la base de datos para que pueda enumerarlos.


2

Tomar datos de DataBase sin ordenar es lo mismo que tomar aleatoriamente


Ciertamente no es aleatorio, aunque no se garantiza que los resultados sean repetibles, pero hay muchas veces que desea hacerlo, especialmente en las pruebas.
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

Tuve que usar el método Take (n), luego transformar a la lista, funcionó como un 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

De esta manera funcionó para mí:

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

Acabo de editar su publicación, traduje el texto portugués al inglés, porque este sitio es solo en inglés (no se aplica a nombres de variables, es por eso que no los he cambiado).
waka

Lo siento ! No me di cuenta, pensé que estaba en el stackoverflow brasileño. Lo siento
Gladson Reis

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.