Linq to SQL TOP veya LIMIT / OFFSET ile eşdeğerdir?


Yanıtlar:


146

VB'de:

from m in MyTable
take 10
select m.Foo

Bu, MyTable'ın IQueryable uyguladığını varsayar. Buna bir DataContext veya başka bir sağlayıcı aracılığıyla erişmeniz gerekebilir.

Ayrıca Foo'nun MyTable'da bir özellik adıyla eşlenen bir sütun olduğunu varsayar.

Daha fazla bilgi için http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx adresine bakın .


127
Bu C # 'da işe yaramıyor, alma ifadesi yok. Take () yöntemini kullanmanız gerekir.
Adam Lassek

10
Teknik olarak, sorgulayan Linq to SQL istedi, bu yüzden VB uygulanabilir bir varsayımdır. Bununla birlikte, ALassek, ben kendimim ve cevabınızı tercih ediyorum. :-)
David Alpert

3
Eh, örnek C # LINQ ile yazılmış, bu yüzden işaret etti.
Adam Lassek

3
2 problem: 1) Bu VB'de iyi çalışıyor. C # 'da Take metoduna sahipsiniz. 2) almak db değil, müşteri çalışır, bu yüzden büyük bir sonuç kümesi varsa db istemciye hepsini almak sonunda!
Yuki

8
Bunun birkaç yaşında olduğunu takdir edin, ancak buraya gelenler için ".Take (x)" ifadesinin ".Select ()" veya ".ToList ()" ifadesini " .Take (x) "yalnızca sonuçları numaralandırmadan önce oluşturulmuş SQL'e dahil edilir. Bundan sonra ortaya çıkarsa, sonuç kümesi numaralandırıldıktan sonra yapılacaktır ve bu nedenle eski bir Linq ifadesidir!
Bertie

248

Take yöntemini kullanın :

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

VB LINQ bir alma ifadesi var:

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

Belgelerden:

Take<TSource>sourceelemanlar verilinceye countveya sourcedaha fazla eleman içermeyene kadar elemanları numaralandırır ve verir . Eğer countöğe sayısını aşıyor source, tüm elemanlar arasında sourcedöndürülür.


13
C # ve VB arasındaki LINQ'daki küçük farklar sinir bozucu. Neden C #, VB gibi bir alma ifadesine sahip değil? Bu bir gözetim gibi görünüyor. Ve VB'nin anonim Subs eksikliği lambdasları çok daha az kullanışlı hale getirir.
Adam Lassek

Tam aradığım şey +1
jasonco

1
+1 Tam da ihtiyacım olan şey. Ve FWIW, sadece on kaydın gerçekte borudan indiği anlaşılıyor. SELECT'im, aksi halde ağrılı bir gecikmeden sonra OutOfMemoryException özel durumunu atacak kadar büyük miktarda veri döndürür . Take ( yönetilebilir miktar ) ile gecikme yok, istisna yok.
Bob Kaufman

VB'nin de bir Take () yöntemi var. Ben miktar için bir değişken kullanmak zorunda kaldı ve yöntem işe yaramadı, ifade işe yaramadı.
Dave Johnson

33

Take(int n)Yöntemi kullanın :

var q = query.Take(10);

25

OP aslında ofsetten de bahsetti. 30 ila 60 arasında ürün almak istiyorsanız, şunları yapardınız:

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

Ofset için "Atla" yöntemini kullanın.
Sınır için "Take" yöntemini kullanın.


13

@ Janei: benim ilk yorum burada senin örnek hakkında;)

Eğer böyle yaparsanız, 4 almak, daha sonra bu 4 üzerinde sıralama uygulamak istiyorum düşünüyorum.

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

Tüm tbl_News değerlerini idNews'e göre azalan ve sonra 4 alarak sıralamaktan farklı

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

Hayır ? sonuçlar farklı olabilir.


5

Bu C # iyi çalışır

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

4

Bunu beğendim:

 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
Bu yaklaşımla ilgili sorun, 4'ü alıp daha sonra sipariş vermenizdir, gerçekten istediğiniz şeyden en iyi 4 sonucu elde etmek olduğundan şüphelendiğimde. Sen sipariş sonra almak gerekir, bkz Yanns yorum.
Russell Troywest


3

Alıcının istemcide mi yoksa db'de mi olacağı, alma işlecini nereye uyguladığınıza bağlıdır. Sorguyu numaralandırmadan önce (yani bir foreach içinde kullanmadan veya bir koleksiyona dönüştürmeden önce) uygularsanız, "top n" SQL operatörü db'ye gönderilir. SQL profiler çalıştırırsanız bunu görebilirsiniz. Sorguyu numaralandırdıktan sonra alma işlemini uygularsanız, istemcide gerçekleşir, çünkü LINQ, verileri numaralandırmanız için veritabanından veri almak zorunda kalacaktır.


2

DataBase verilerini sıralama yapmadan almak rastgele alma ile aynıdır


Sonuçların tekrarlanabilir olduğu garanti edilmese de kesinlikle rastgele değil, ancak bunu özellikle testte yapmak istediğiniz birçok zaman var.
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

Take (n) yöntemini kullanmak zorunda kaldım, sonra listeye dönüştüm, Bir cazibe gibi çalıştım:

    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

Bu şekilde benim için çalıştı:

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

Yazınızı yeni düzenledim, portekizce metni ingilizceye çevirdim, çünkü bu site sadece ingilizce dilidir (değişken isimlere uygulanmaz, bu yüzden bunları değiştirmedim).
waka

Afedersiniz ! Fark etmedim, Brezilya yığın akışında olduğumu sanıyordum. Üzgünüz
Gladson Reis

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.