So wählen Sie nur die Datensätze mit dem höchsten Datum in LINQ aus

117

Ich habe eine Tabelle, 'lasttraces', mit den folgenden Feldern.

Id, AccountId, Version, DownloadNo, Date

Die Daten sehen folgendermaßen aus:

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

Wie kann ich in LINQ to SQL nur die letzte letzte Spur jeder AccountId abrufen (die mit dem höchsten Datum)?

Bas Jansen
quelle
In Ihrem Beispiel haben tatsächlich alle Protokolle mit derselben Konto-ID genau dasselbe Datum. Welches Protokoll wird in diesem Fall bevorzugt?
BlackTigerX

Antworten:

230

Wenn Sie nur das letzte Datum für jedes Konto möchten, verwenden Sie Folgendes:

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

Wenn Sie die gesamte Aufzeichnung möchten:

var q = from n in table
        group n by n.AccountId into g
        select g.OrderByDescending(t=>t.Date).FirstOrDefault();
Mehrdad Afshari
quelle
2
Oracle unterstützt dies nicht. Wenn die Abfrageleistung nicht berücksichtigt wird, können Sie die Tabelle ToList konvertieren, bevor Sie die Abfrage ausführen.
Will Wu
8
Es wäre toll, wenn Sie eine method-chainLösung dafür posten könnten .
LCJ
zweite Abfrage - sollte es nicht sein (from n in table ...).First()?
Jason L
@ JasonL, nein. Der First()Aufruf sollte für den g.Order...Ausdruck (Unterabfrage) gelten.
Mehrdad Afshari
1
@Mehrdad Afshari das ist erstaunlich , ich wollte in erster Linie die zweite, aber beide sind jetzt in meinen Schnipsel als so sehr nützlich . Danke danke danke!!!!!
Andrew Day
52

Hier ist eine einfache Möglichkeit, dies zu tun

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

Schauen Sie sich auch diesen großartigen LINQ-Ort an - LINQ to SQL-Beispiele

Entwickler
quelle
25
Diese Lösung funktioniert einwandfrei, wenn Sie pro Konto abgefragt haben, aber nicht das tun, was OP angegeben hat. Dies bedeutet, das aktuellste Ergebnis für alle Datensätze zu erhalten, ohne eine AccountId (in Ihrem Fall PlayerId) anzugeben
Maciej
1
Diese Lösung hat mich dazu inspiriert, stattdessen zu bestellen und zu versuchen, das Maximum auszuwählen. +1
Razvan Dumitru
Diese Lösung kann dazu führen, dass "Sequenz enthält keine Elemente" Fehler in Linq richtig?
xSkrappy
34

Wenn Sie die gesamte Aufzeichnung möchten, ist hier ein Lambda-Weg:

var q = _context
             .lasttraces
             .GroupBy(s => s.AccountId)
             .Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());
Bob Zhang
quelle
1
Hat super funktioniert. Vielen Dank.
Terry
Dies ist der Schlüssel hier.
Jason P Sallinger
5

Es könnte so etwas sein wie:

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) };
bruno conde
quelle
3

Gehen Sie einen einfachen Weg, um dies zu tun: -

Erstellt eine Klasse für die folgenden Informationen

  • Level (Nummer)
  • URL (URL der Site)

Gehen Sie zur Liste der Sites, die in einem ArrayList-Objekt gespeichert sind. Und folgende Abfrage ausgeführt, um sie in absteigender Reihenfolge nach Ebene zu sortieren.

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

Nachdem ich die Sammlung in absteigender Reihenfolge sortiert hatte, schrieb ich den folgenden Code, um das Objekt zu erhalten, das als oberste Zeile kommt

MyClass topObject = query.FirstRow<MyClass>()

Das funktionierte wie Charme.

Sudhir Kesharwani
quelle
Dies gab mir eine bessere Idee als mein ursprünglicher Gedanke. Vielen Dank!
Paulj