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

195

Jak mam to zrobic

Select top 10 Foo from MyTable

w Linq na SQL?

Herb Caudill
źródło

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 .

David Alpert
źródło
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.

Adam Lassek
źródło
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
33

Użyj Take(int n)metody:

var q = query.Take(10);
amcoder
źródło
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ź”.

Inc33
źródło
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.

Yann
źródło
5

Działa to dobrze w C #

var q = from m in MyTable.Take(10)
        select m.Foo
spdrcr911
źródło
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
                };
Janei Vieira
źródło
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

Użyłbyś metody Take (N).

FlySwat
źródło
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ć

użytkownik124368
źródło
2

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

Anton
źródło
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();
minhnguyen
źródło
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();
OPROGRAMOWANIE Apollo
źródło
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;
Gladson Reis
źródło
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
0

Do limit 1metod użycia FirstOrDefault()lub First().

Przykład

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

Deweloper Marius Žilėnas
źródło