Was entspricht Linq to SQL TOP oder LIMIT / OFFSET?


Antworten:


146

In VB:

from m in MyTable
take 10
select m.Foo

Dies setzt voraus, dass MyTable IQueryable implementiert. Möglicherweise müssen Sie über einen DataContext oder einen anderen Anbieter darauf zugreifen.

Es wird auch davon ausgegangen, dass Foo eine Spalte in MyTable ist, die einem Eigenschaftsnamen zugeordnet wird.

Weitere Informationen finden Sie unter http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx .


127
Das funktioniert in C # nicht, es gibt keinen Take-Ausdruck. Sie müssen die Take () -Methode verwenden.
Adam Lassek

10
Technisch gesehen hat der Fragesteller nach Linq to SQL gefragt, daher ist VB eine tragfähige Annahme. Das heißt, ALassek, ich bin selbst ein Typ und bevorzuge deine Antwort. :-)
David Alpert

3
Nun, Ihr Beispiel wurde in C # LINQ geschrieben, weshalb ich darauf hingewiesen habe.
Adam Lassek

3
2 Probleme: 1) Dies funktioniert gut in VB. In C # haben Sie die Take-Methode. 2) Die Aufnahme funktioniert im Client, nicht in der Datenbank. Wenn Sie also eine große Ergebnismenge haben, erhalten Sie am Ende alles von der Datenbank zum Client!
Yuki

8
Schätzen Sie, dass dies ein paar Jahre alt ist, aber für diejenigen, die gerade erst hierher kommen, ist es erwähnenswert, dass ".Take (x)" angezeigt werden sollte, bevor Sie ".Select ()" oder ".ToList ()" als ". .Take (x) "wird nur dann in die generierte SQL aufgenommen, wenn Sie die Ergebnisse aufgelistet haben. Wenn es danach erscheint, wird es durchgeführt, sobald die Ergebnismenge aufgezählt wurde und daher eine einfache alte Linq-Anweisung ist!
Bertie

248

Verwenden Sie die Take-Methode :

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

In VB hat LINQ einen Take-Ausdruck:

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

Aus der Dokumentation:

Take<TSource>zählt sourceElemente auf und ergibt sie, bis countElemente ergeben wurden oder sourcekeine Elemente mehr enthalten. Wenn countdie Anzahl der Elemente in überschritten wird source, werden alle Elemente von sourcezurückgegeben.


13
Die kleinen Unterschiede im LINQ zwischen C # und VB sind ärgerlich. Warum hat C # keinen Take-Ausdruck wie VB? Das scheint ein Versehen zu sein. Und das Fehlen anonymer Subs von VB macht Lambdas viel weniger nützlich.
Adam Lassek

Genau das, wonach ich gesucht habe +1
jasonco

1
+1 Genau das, was ich auch brauchte. Und FWIW scheint, dass nur die zehn Platten tatsächlich in die Pfeife kommen. Mein SELECT würde andernfalls eine enorme Datenmenge zurückgeben, die ausreicht, um nach einer schmerzhaften Verzögerung eine OutOfMemoryException auszulösen . Mit Take ( überschaubare Menge ) keine Verzögerung, keine Ausnahme.
Bob Kaufman

VB hat jetzt auch eine Take () -Methode. Ich musste eine Variable für den Betrag verwenden, und der Ausdruck funktionierte nicht, während die Methode dies tat.
Dave Johnson

33

Verwenden Sie die Take(int n)Methode:

var q = query.Take(10);

24

Das OP erwähnte tatsächlich auch den Versatz, also zum Beispiel. Wenn Sie die Artikel von 30 bis 60 erhalten möchten, würden Sie Folgendes tun:

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

Verwenden Sie die Methode "Überspringen" für den Versatz.
Verwenden Sie die "Take" -Methode als Limit.


13

@ Janei: Mein erster Kommentar hier ist über deine Probe;)

Ich denke, wenn dir das gefällt, möchtest du 4 nehmen und dann die Sortierung auf diese 4 anwenden.

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

Anders als das Sortieren ganzer tbl_News nach absteigenden idNews und anschließendem Nehmen von 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);

Nein ? Ergebnisse können unterschiedlich sein.


5

Dies funktioniert gut in C #

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

4

Ich mag das:

 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
Das Problem bei diesem Ansatz ist, dass Sie 4 nehmen und sie dann bestellen, wenn ich vermute, dass Sie wirklich die besten 4 Ergebnisse erzielen möchten. Sie müssen die Aufnahme nach der Bestellung machen, siehe Yanns Kommentar.
Russell Troywest


3

Ob der Take auf dem Client oder in der Datenbank stattfindet, hängt davon ab, wo Sie den Take-Operator anwenden. Wenn Sie es anwenden, bevor Sie die Abfrage aufzählen (dh bevor Sie es in einem foreach verwenden oder in eine Sammlung konvertieren), führt der Take dazu, dass der SQL-Operator "top n" an die Datenbank gesendet wird. Sie können dies sehen, wenn Sie den SQL-Profiler ausführen. Wenn Sie den Take nach dem Auflisten der Abfrage anwenden, geschieht dies auf dem Client, da LINQ die Daten aus der Datenbank abrufen musste, damit Sie sie auflisten können


2

Das Aufnehmen von Daten aus der Datenbank ohne Sortieren entspricht dem zufälligen Aufnehmen


Es ist sicherlich nicht zufällig, obwohl die Ergebnisse nicht garantiert wiederholbar sind, aber es gibt viele Fälle, in denen Sie dies tun möchten, insbesondere beim Testen.
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

Ich musste die Take (n) -Methode verwenden und dann in eine Liste umwandeln. Arbeitete wie ein Zauber:

    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

So hat es bei mir funktioniert:

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

Ich habe gerade Ihren Beitrag bearbeitet und den portugiesischen Text ins Englische übersetzt, da diese Seite nur in englischer Sprache verfasst ist (gilt nicht für Variablennamen, deshalb habe ich diese nicht geändert).
Waka

Es tut uns leid ! Ich wusste nicht, ich dachte, ich wäre im brasilianischen Stackoverflow. Entschuldigung
Gladson Reis

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.