Linq ไปยัง SQL เทียบเท่ากับ TOP หรือ LIMIT / OFFSET คืออะไร


คำตอบ:


146

ใน VB:

from m in MyTable
take 10
select m.Foo

นี่ถือว่า MyTable ใช้ IQueryable คุณอาจต้องเข้าถึงผ่าน DataContext หรือผู้ให้บริการรายอื่น

นอกจากนี้ยังถือว่า Foo เป็นคอลัมน์ใน MyTable ที่แมปกับชื่อคุณสมบัติ

ดูhttp://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspxสำหรับรายละเอียดเพิ่มเติม


127
ใช้งานไม่ได้ใน C # ไม่มีการแสดงออก คุณต้องใช้วิธีใช้ ()
Adam Lassek

10
ในทางเทคนิคผู้ถามถาม Linq กับ SQL ดังนั้น VB จึงเป็นข้อสมมติที่ใช้การได้ ที่กล่าวว่า ALassek ฉันเป็นผู้ชาย # ตัวเองและชอบคำตอบของคุณ :-)
David Alpert

3
ตัวอย่างคุณเขียนใน C # LINQ ซึ่งเป็นเหตุผลที่ฉันชี้ให้เห็น
Adam Lassek

3
2 ปัญหา: 1) สิ่งนี้ทำงานได้ดีใน VB ใน C # คุณมีวิธีใช้ 2) การใช้งานในไคลเอนต์ไม่ใช่ใน db ดังนั้นหากคุณมีชุดผลลัพธ์ขนาดใหญ่คุณจะได้รับมันทั้งหมดไปยังไคลเอนต์จาก db!
ยูกิ

8
ชื่นชมสิ่งนี้อายุไม่กี่ปี แต่สำหรับผู้ที่เพิ่งมาถึงที่นี่เป็นสิ่งที่ควรสังเกตว่า ".Take (x)" ควรปรากฏก่อนที่คุณจะทำ ".Select ()" หรือ ". ToList ()" เป็น " .Take (x) "จะรวมอยู่ใน SQL ที่สร้างขึ้นหากเป็นก่อนที่คุณจะระบุผลลัพธ์ หากปรากฏขึ้นหลังจากนี้จะมีการดำเนินการเมื่อชุดผลลัพธ์ถูกแจกแจงและดังนั้นจึงเป็นคำสั่ง Linq แบบเก่า!
Bertie

248

ใช้วิธีใช้ :

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

ใน VB LINQ มีการแสดงออก:

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

จากเอกสาร:

Take<TSource>แจกแจงsourceและให้องค์ประกอบจนกว่าจะcountได้รับองค์ประกอบหรือsourceไม่มีองค์ประกอบเพิ่มเติม หากcountเกินจำนวนองค์ประกอบในsourceองค์ประกอบทั้งหมดของsourceจะถูกส่งกลับ


13
ความแตกต่างเล็กน้อยใน LINQ ระหว่าง C # และ VB นั้นน่ารำคาญ เหตุใด C # จึงไม่มีนิพจน์เหมือน VB ดูเหมือนว่าการกำกับดูแล และการที่ VB ขาด Subs Subs ทำให้ lambdas นั้นมีประโยชน์น้อยกว่ามาก
Adam Lassek

สิ่งที่ฉันกำลังมองหา +1
jasonco

1
+1 สิ่งที่ฉันต้องการเช่นกัน และ FWIW ดูเหมือนว่ามีเพียงสิบระเบียนจริงลงมาท่อ My SELECT จะส่งคืนข้อมูลจำนวนมหาศาลเพียงพอที่จะส่งOutOfMemoryExceptionหลังจากความล่าช้าอันเจ็บปวด ด้วย Take ( Manageable-ปริมาณ ), ไม่ล่าช้า, ไม่มีข้อยกเว้น
Bob Kaufman

VB ตอนนี้มีวิธีใช้ () เช่นกัน ฉันต้องใช้ตัวแปรเพื่อให้ได้ปริมาณและการแสดงออกไม่ทำงานในขณะที่วิธีการทำ
Dave Johnson


25

OP จริง ๆ กล่าวถึงการชดเชยเช่นกันดังนั้นสำหรับอดีต หากคุณต้องการรับสินค้าตั้งแต่ 30 ถึง 60 คุณจะทำ:

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

ใช้วิธี "ข้าม" เพื่อชดเชย
ใช้วิธี "รับ" เพื่อ จำกัด


13

@ Janei: ความคิดเห็นแรกของฉันที่นี่เป็นเรื่องเกี่ยวกับตัวอย่างของคุณ;)

ฉันคิดว่าถ้าคุณทำแบบนี้คุณอยากได้ 4 แล้วใช้การจัดเรียงกับ 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
                };

แตกต่างจากการเรียงลำดับ tbl_News ทั้งหมดโดย idNews จากมากไปน้อยแล้วเลือก 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);

ไม่นะ ผลลัพธ์อาจแตกต่างกัน



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

7
ปัญหาของวิธีนี้คือคุณจะต้องใช้ 4 และสั่งให้พวกเขาเมื่อฉันสงสัยว่าสิ่งที่คุณต้องการจริงๆคือการได้รับผลลัพธ์สูงสุด 4 อันดับแรก คุณต้องทำตามคำสั่งซื้อโดยดูที่ความคิดเห็นของยานน์
Russell Troywest


3

ไม่ว่าจะเกิดขึ้นกับลูกค้าหรือใน db ขึ้นอยู่กับตำแหน่งที่คุณใช้ประกอบการ หากคุณนำไปใช้ก่อนที่จะระบุแบบสอบถาม (เช่นก่อนที่คุณจะใช้มันใน foreach หรือแปลงเป็นคอลเลกชัน) การใช้จะส่งผลให้ผู้ประกอบการ SQL "top n" ถูกส่งไปยัง db คุณสามารถเห็นสิ่งนี้หากคุณเรียกใช้ SQL profiler ถ้าคุณใช้การหลังจากแจกแบบสอบถามมันจะเกิดขึ้นบนไคลเอนต์เป็น LINQ จะต้องดึงข้อมูลจากฐานข้อมูลเพื่อให้คุณระบุผ่านมัน


2

การรับข้อมูลของ DataBase โดยไม่มีการเรียงลำดับจะเหมือนกับการสุ่ม


แน่นอนว่าไม่ใช่การสุ่มแม้ว่าผลลัพธ์จะไม่รับประกันว่าจะสามารถทำซ้ำได้ แต่มีหลายครั้งที่คุณต้องการทำเช่นนั้นโดยเฉพาะอย่างยิ่งในการทดสอบ
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) จากนั้นแปลงเป็นรายการทำงานเหมือนเครื่องราง:

    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

วิธีนี้ใช้ได้ผลกับฉัน:

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

ฉันเพิ่งแก้ไขโพสต์ของคุณฉันแปลข้อความภาษาโปรตุเกสเป็นภาษาอังกฤษเนื่องจากไซต์นี้เป็นภาษาอังกฤษเท่านั้น (ไม่ได้ใช้กับชื่อตัวแปรนั่นคือเหตุผลที่ฉันไม่ได้เปลี่ยนสิ่งเหล่านั้น)
waka

ขออภัยด้วย! ฉันไม่ได้ตระหนักถึงฉันคิดว่าฉันอยู่ในกองซ้อนของบราซิล ขออภัย
Gladson Reis

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.