Co to jest Linq to SQL równoważne z TOP lub LIMIT / OFFSET?


Odpowiedzi:


146

W VB:

from m in MyTable
take 10
select m.Foo

Zakłada się, że MyTable implementuje IQueryable. Być może będziesz musiał uzyskać do nich dostęp za pośrednictwem DataContext lub innego dostawcy.

Zakłada również, że Foo to kolumna w MyTable, która jest mapowana na nazwę właściwości.

Więcej informacji można znaleźć na stronie http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx .


127
To nie działa w języku C #, nie ma wyrażenia. Musisz użyć metody Take ().
Adam Lassek,

10
Technicznie pytający poprosił o Linq na SQL, więc VB jest realnym założeniem. To powiedziawszy, ALassek, sam jestem facetem i wolę twoją odpowiedź. :-)
David Alpert,

3
Cóż, twój przykład został napisany w C # LINQ i dlatego zwróciłem na to uwagę.
Adam Lassek,

3
2 problemy: 1) działa dobrze w VB. w C # masz metodę Take. 2) wykonanie działa w kliencie, a nie w db, więc jeśli masz duży zestaw wyników, w końcu dostaniesz wszystko do klienta z db!
Yuki,

8
Doceń to, że ma już kilka lat, ale dla tych, którzy dopiero się tu dostają, warto zauważyć, że „.Take (x)” powinien pojawić się przed wykonaniem „.Select ()” lub „.ToList ()”, jako „ .Take (x) ”zostanie uwzględniony w wygenerowanym SQL tylko wtedy, gdy nastąpi to przed wyliczeniem wyników. Jeśli pojawi się po tym, nastąpi to po wyliczeniu zestawu wyników, a zatem jest zwykłą starą instrukcją Linq!
Bertie,

248

Użyj metody Take :

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

W VB LINQ ma wyrażenie:

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

Z dokumentacji:

Take<TSource>wylicza sourcei daje elementy, dopóki countelementy nie zostaną uzyskane lub sourcenie będzie więcej elementów. Jeśli countprzekroczy liczbę elementów source, wszystkie elementy sourcesą zwracane.


13
Małe różnice w LINQ między C # i VB są denerwujące. Dlaczego C # nie ma wyrażenia typu VB? To wydaje się niedopatrzeniem. Brak anonimowych subskrybentów VB sprawia, że ​​lambdas są znacznie mniej przydatne.
Adam Lassek,

Właśnie tego szukałem +1
Jasonco

1
+1 Właśnie tego potrzebowałem. I FWIW, wygląda na to, że tylko dziesięć płyt faktycznie schodzi z fajki. Mój SELECT w przeciwnym razie zwróciłby ogromną ilość danych, wystarczającą do wyrzucenia OutOfMemoryException po bolesnym opóźnieniu. Z Take ( ilość zarządzalna ), bez opóźnień, bez wyjątku.
Bob Kaufman

VB ma teraz również metodę Take (). Musiałem użyć zmiennej do pobrania kwoty, a wyrażenie nie działało, podczas gdy metoda działała.
Dave Johnson


25

OP faktycznie wspomniał także o przesunięciu, więc np. jeśli chcesz dostać przedmioty od 30 do 60, zrobiłbyś:

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

Do przesunięcia użyj metody „Pomiń”.
Do ograniczenia użyj metody „Weź”.


13

@Janei: mój pierwszy komentarz tutaj dotyczy twojej próbki;)

Myślę, że jeśli ci się tak podoba, chcesz wziąć 4, a następnie zastosować sortowanie na tych 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
                };

Różni się od sortowania całych tbl_News według idNews malejąco, a następnie biorąc 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);

nie? wyniki mogą być inne.



4

Lubię to:

 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
Problem z tym podejściem polega na tym, że weźmiesz 4, a następnie zamówisz je, gdy podejrzewam, że naprawdę chcesz uzyskać 4 najlepsze wyniki. Musisz zrobić zdjęcie po zamówieniu, patrz komentarz Yanns.
Russell Troywest


3

To, czy operacja wykonania ma miejsce na kliencie, czy w bazie danych, zależy od tego, gdzie zastosujesz operatora. Jeśli zastosujesz je przed wyliczeniem zapytania (tj. Zanim użyjesz go w foreach lub skonwertujesz na kolekcję), wykonanie spowoduje wysłanie do bazy danych SQL operatora „top n”. Możesz to zobaczyć, jeśli uruchomisz profiler SQL. Jeśli zastosujesz ujęcie po wyliczeniu zapytania, stanie się ono na kliencie, ponieważ LINQ będzie musiał pobrać dane z bazy danych, aby je wyliczyć


2

Pobieranie danych z bazy danych bez sortowania jest tym samym, co pobieranie losowe


Z pewnością nie jest losowy, chociaż wyniki nie są powtarzalne, ale jest wiele razy, aby to zrobić, szczególnie w testach.
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

Musiałem użyć metody Take (n), a następnie przekształcić na listę, działał jak urok:

    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

W ten sposób zadziałało dla mnie:

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

Właśnie edytowałem twój post, przetłumaczyłem tekst portugalski na angielski, ponieważ ta strona jest tylko w języku angielskim (nie dotyczy nazw zmiennych, dlatego ich nie zmieniłem).
waka

Przepraszam Nie zdawałem sobie sprawy, myślałem, że jestem w brazylijskim przepełnieniu stosu. Przepraszamy
Gladson Reis

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.