Apa Linq to SQL yang setara dengan TOP atau LIMIT / OFFSET?

195

Bagaimana saya melakukan ini

Select top 10 Foo from MyTable

dalam Linq ke SQL?

Ramuan Caudill
sumber

Jawaban:

146

Dalam VB:

from m in MyTable
take 10
select m.Foo

Ini mengasumsikan bahwa MyTable mengimplementasikan IQueryable. Anda mungkin harus mengaksesnya melalui DataContext atau penyedia lain.

Itu juga mengasumsikan bahwa Foo adalah kolom di MyTable yang dipetakan ke nama properti.

Lihat http://blogs.msdn.com/vbteam/archive/2008/01/08/mengonversi-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx untuk detail lebih lanjut.

David Alpert
sumber
127
Itu tidak bekerja di C #, tidak ada ekspresi take. Anda perlu menggunakan metode Take ().
Adam Lassek
10
Secara teknis, penanya meminta Linq ke SQL, jadi VB adalah asumsi yang layak. Yang mengatakan, ALassek, saya ac # guy sendiri dan lebih suka jawaban Anda. :-)
David Alpert
3
Nah, contoh Anda ditulis dalam C # LINQ itulah sebabnya saya menunjukkan itu.
Adam Lassek
3
2 masalah: 1) ini berfungsi dengan baik di VB. di C # Anda memiliki metode Take. 2) take works di klien, bukan di db, jadi jika Anda memiliki hasil yang besar, Anda akan mendapatkan semua itu untuk klien dari db!
Yuki
8
Hargai ini beberapa tahun, tetapi bagi mereka yang baru saja tiba di sini, perlu dicatat bahwa ". Take (x)" akan muncul sebelum Anda melakukan ". Pilih ()" atau ".ToList ()", sebagai " . Take (x) "hanya akan dimasukkan dalam SQL yang dihasilkan jika sebelum Anda menyebutkan hasilnya. Jika muncul setelah ini, maka itu akan dilakukan setelah set hasil telah disebutkan dan oleh karena itu pernyataan Linq tua yang sederhana!
Bertie
248

Gunakan metode Ambil :

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

Dalam VB, LINQ memiliki ekspresi take:

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

Dari dokumentasi:

Take<TSource>menghitung sourcedan menghasilkan elemen sampai countelemen telah dihasilkan atau sourcetidak mengandung elemen lagi. Jika countmelebihi jumlah elemen dalam source, semua elemen sourcedikembalikan.

Adam Lassek
sumber
13
Perbedaan kecil dalam LINQ antara C # dan VB menjengkelkan. Mengapa C # tidak memiliki ekspresi take seperti VB? Sepertinya itu kekhilafan. Dan kurangnya VB dari Subs anonim membuat lambdas jauh lebih berguna.
Adam Lassek
Hanya apa yang saya cari +1
jasonco
1
+1 Hanya yang saya butuhkan juga. Dan FWIW, tampaknya hanya sepuluh catatan yang benar-benar turun ke pipa. Saya SELECT jika tidak akan mengembalikan besar jumlah data, cukup untuk melemparkan sebuah OutOfMemoryException setelah penundaan yang menyakitkan. Dengan Take ( dikelola-kuantitas ), tidak ada penundaan, tidak terkecuali.
Bob Kaufman
VB sekarang memiliki metode Take () juga. Saya harus menggunakan variabel untuk jumlah yang akan diambil, dan ekspresi tidak bekerja, sementara metode itu.
Dave Johnson
33

Gunakan Take(int n)metode:

var q = query.Take(10);
amcoder
sumber
25

OP sebenarnya menyebutkan offset juga, jadi untuk ex. jika Anda ingin mendapatkan item dari 30 hingga 60, Anda akan melakukan:

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

Gunakan metode "Lewati" untuk offset.
Gunakan metode "Ambil" untuk batas.

Termasuk33
sumber
13

@ Janei: komentar pertama saya di sini adalah tentang sampel Anda;)

Saya pikir jika Anda suka ini, Anda ingin mengambil 4, kemudian menerapkan jenis pada 4 ini.

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

Berbeda dengan memilah seluruh tbl_News oleh idNews turun lalu mengambil 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);

tidak ? hasilnya mungkin berbeda.

Yann
sumber
5

Ini bekerja dengan baik di C #

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

Saya suka ini:

 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
sumber
7
Masalah dengan pendekatan ini adalah bahwa Anda akan mengambil 4 dan kemudian memesannya, ketika saya menduga apa yang Anda inginkan adalah mendapatkan 4 hasil teratas. Anda perlu melakukan take setelah orderby, lihat komentar Yanns.
Russell Troywest
3

Anda akan menggunakan metode Take (N).

FlySwat
sumber
3

Apakah take terjadi pada klien atau dalam db tergantung di mana Anda menerapkan operator take. Jika Anda menerapkannya sebelum Anda menghitung kueri (yaitu sebelum Anda menggunakannya dalam foreach atau mengubahnya menjadi koleksi), pengambilan akan menghasilkan "SQL top" operator SQL yang dikirim ke db. Anda dapat melihat ini jika Anda menjalankan SQL profiler. Jika Anda menerapkan pengambilan setelah menghitung kueri itu akan terjadi pada klien, karena LINQ harus mengambil data dari database agar Anda menghitungnya.

pengguna124368
sumber
2

Mengambil data dari DataBase tanpa mengurutkan sama dengan pengambilan acak

Anton
sumber
Ini tentu saja tidak acak, meskipun hasilnya tidak dijamin dapat diulang, tetapi ada banyak kali Anda ingin melakukan itu, terutama dalam pengujian.
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
sumber
0

Saya harus menggunakan metode Take (n), lalu bertransformasi menjadi daftar, Berfungsi seperti pesona:

    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();
PERANGKAT LUNAK Apollo
sumber
0

Cara ini berhasil bagi saya:

var noticias = from n in db.Noticias.Take(6)
                       where n.Atv == 1
                       orderby n.DatHorLan descending
                       select n;
Gladson Reis
sumber
Saya baru saja mengedit posting Anda, saya menerjemahkan teks Portugis ke dalam bahasa Inggris, karena situs ini hanya bahasa Inggris (tidak berlaku untuk nama variabel, itu sebabnya saya belum mengubahnya).
waka
Maaf! Saya tidak menyadari, saya pikir saya berada di stackoverflow Brasil. Maaf
Gladson Reis
0

Untuk limit 1menggunakan metode FirstOrDefault()atau First().

Contoh

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

Pengembang Marius Žilėnas
sumber