วิธีเลือกเฉพาะระเบียนที่มีวันที่สูงสุดใน LINQ


117

ฉันมีตาราง 'lasttraces' พร้อมช่องต่อไปนี้

Id, AccountId, Version, DownloadNo, Date

ข้อมูลมีลักษณะดังนี้:

28092|15240000|1.0.7.1782|2009040004731|2009-01-20 13:10:22.000
28094|61615000|1.0.7.1782|2009040007696|2009-01-20 13:11:38.000
28095|95317000|1.0.7.1782|2009040007695|2009-01-20 13:10:18.000
28101|15240000|1.0.7.1782|2009040004740|2009-01-20 14:10:22.000
28103|61615000|1.0.7.1782|2009040007690|2009-01-20 14:11:38.000
28104|95317000|1.0.7.1782|2009040007710|2009-01-20 14:10:18.000

ฉันจะรับเฉพาะ Lasttrace ของทุก AccountId ในLINQในLINQได้อย่างไร (อันที่มีวันที่สูงสุด)


จริงๆแล้วในตัวอย่างของคุณบันทึกทั้งหมดที่มีรหัสบัญชีเดียวกันมีวันที่เดียวกันดังนั้นข้อใดจึงควรใช้ในกรณีนี้
BlackTigerX

คำตอบ:


231

หากคุณต้องการเพียงวันที่สุดท้ายของแต่ละบัญชีคุณจะต้องใช้สิ่งนี้:

var q = from n in table
        group n by n.AccountId into g
        select new {AccountId = g.Key, Date = g.Max(t=>t.Date)};

หากคุณต้องการบันทึกทั้งหมด:

var q = from n in table
        group n by n.AccountId into g
        select g.OrderByDescending(t=>t.Date).FirstOrDefault();

2
Oracle ไม่รองรับสิ่งนี้ หากประสิทธิภาพของแบบสอบถามไม่อยู่ในการพิจารณาของคุณคุณสามารถแปลง ToList ของตารางก่อนที่คุณจะทำแบบสอบถาม
Will Wu

8
จะดีมากถ้าคุณสามารถโพสต์method-chainวิธีแก้ปัญหานี้ได้
LCJ

คำถามที่สอง - ควร(from n in table ...).First()หรือไม่
Jason L

@JasonL เลขที่ การFirst()เรียกควรใช้กับg.Order...นิพจน์ (เคียวรีย่อย)
Mehrdad Afshari

1
@Mehrdad Afshari thats ที่น่าตื่นตาตื่นใจฉันต้องการคนที่สองเป็นหลัก แต่พวกเขามีทั้งที่ขณะนี้อยู่ในเกร็ดเล็กเกร็ดน้อยของฉันเป็นเพื่อประโยชน์อย่างมาก ขอบคุณขอบคุณขอบคุณ!!!!!
Andrew Day

52

นี่คือวิธีง่ายๆในการทำ

var lastPlayerControlCommand = this.ObjectContext.PlayerControlCommands
                                .Where(c => c.PlayerID == player.ID)
                                .OrderByDescending(t=>t.CreationTime)
                                .FirstOrDefault();

ลองดูสถานที่ LINQ ที่ยอดเยี่ยมนี้ด้วยเช่นLINQ ถึง SQL Samples


25
วิธีนี้ใช้งานได้ดีหากคุณกำลังค้นหาต่อบัญชี แต่ไม่ได้ทำตามที่ OP ระบุไว้ซึ่งจะได้รับผลลัพธ์ล่าสุดสำหรับบันทึกทั้งหมดโดยไม่ต้องให้ AccountId (ในกรณีของคุณคือ PlayerId)
Maciej

1
โซลูชันนี้เป็นแรงบันดาลใจให้ฉันสั่งซื้อแทนเพื่อพยายามเลือกสูงสุด +1
Razvan Dumitru

วิธีนี้อาจทำให้เกิดข้อผิดพลาด "Sequence contains no elements" ใน Linq ใช่หรือไม่?
xSkrappy

34

หากคุณต้องการบันทึกทั้งหมดนี่คือวิธีแลมบ์ดา:

var q = _context
             .lasttraces
             .GroupBy(s => s.AccountId)
             .Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());

1
ทำงานได้ดี ขอบคุณ
Terry

นี่คือกุญแจสำคัญที่นี่
Jason P Sallinger

5

อาจเป็นสิ่งที่ชอบ:

var qry = from t in db.Lasttraces
          group t by t.AccountId into g
          orderby t.Date
          select new { g.AccountId, Date = g.Max(e => e.Date) };

3

ไปที่วิธีง่ายๆในการดำเนินการนี้: -

สร้างหนึ่งคลาสเพื่อเก็บข้อมูลต่อไปนี้

  • ระดับ (จำนวน)
  • URL (URL ของไซต์)

ไปที่รายการไซต์ที่เก็บไว้ในวัตถุ ArrayList และเรียกใช้แบบสอบถามต่อไปนี้เพื่อเรียงลำดับจากมากไปหาน้อยตามระดับ

var query = from MyClass object in objCollection 
    orderby object.Level descending 
    select object

เมื่อฉันได้รับคอลเลกชันที่เรียงลำดับจากมากไปหาน้อยฉันเขียนโค้ดต่อไปนี้เพื่อรับ Object ที่มาเป็นแถวบนสุด

MyClass topObject = query.FirstRow<MyClass>()

สิ่งนี้ได้ผลเหมือนมีเสน่ห์


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