Jak wybrać tylko rekordy z najwyższą datą w LINQ

117

Mam tabelę „lasttraces” z następującymi polami.

Id, AccountId, Version, DownloadNo, Date

Dane wyglądają następująco:

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

Jak mogę, w LINQ to SQL , uzyskać tylko ostatni ślad każdego AccountId (ten z najwyższą datą)?

Bas Jansen
źródło
właściwie w twoim przykładzie wszystkie logi z tym samym identyfikatorem konta mają dokładnie tę samą datę, więc który z nich ma pierwszeństwo w tym przypadku?
BlackTigerX

Odpowiedzi:

230

Jeśli chcesz tylko ostatnią datę dla każdego konta, użyj tego:

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

Jeśli chcesz mieć cały rekord:

var q = from n in table
        group n by n.AccountId into g
        select g.OrderByDescending(t=>t.Date).FirstOrDefault();
Mehrdad Afshari
źródło
2
Oracle tego nie obsługuje. Jeśli nie bierzesz pod uwagę wydajności zapytania, możesz przekonwertować tabelę na listę przed wykonaniem zapytania.
Will Wu
8
Byłoby wspaniale, gdybyś mógł opublikować method-chainrozwiązanie tego problemu.
LCJ
drugie zapytanie - czy nie powinno (from n in table ...).First()?
Jason L
@JasonL, nie. First()Rozmowa powinna mieć zastosowanie do g.Order...wyrażenia (podzapytanie).
Mehrdad Afshari
1
@Mehrdad Afshari, to niesamowite , chciałem przede wszystkim drugiego, ale oba są teraz w moich fragmentach jako bardzo przydatne . Dziekuję Dziekuję Dziękuję!!!!!
Andrew Day
52

Oto prosty sposób na zrobienie tego

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

Zobacz też to świetne miejsce LINQ - LINQ to SQL Samples

Deweloper
źródło
25
To rozwiązanie działa dobrze, jeśli pytałeś o konto, ale nie robisz tego, co podał OP, czyli uzyskać najbardziej aktualny wynik dla wszystkich rekordów bez podawania AccountId (w twoim przypadku PlayerId)
Maciej
1
To rozwiązanie zainspirowało mnie do zamówienia zamiast spróbować wybrać maksimum. +1
Razvan Dumitru
To rozwiązanie może prowadzić do „sekwencji nie zawiera elementów” Błąd w Linq, prawda?
xSkrappy
34

Jeśli chcesz mieć cały rekord, oto sposób lambda:

var q = _context
             .lasttraces
             .GroupBy(s => s.AccountId)
             .Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());
Bob Zhang
źródło
1
Działało świetnie. Dzięki.
Terry
To jest klucz tutaj.
Jason P Sallinger
5

Może to być coś takiego:

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
źródło
3

Idź w prosty sposób, aby to zrobić: -

Utworzono jedną klasę do przechowywania następujących informacji

  • Poziom (liczba)
  • Url (adres URL witryny)

Przejdź do listy witryn przechowywanych w obiekcie ArrayList. I wykonałem następujące zapytanie, aby posortować je w porządku malejącym według poziomu.

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

Po posortowaniu kolekcji w porządku malejącym napisałem następujący kod, aby uzyskać obiekt, który znajduje się w górnym wierszu

MyClass topObject = query.FirstRow<MyClass>()

To zadziałało jak urok.

Sudhir Kesharwani
źródło
To dało mi lepszy pomysł niż moja pierwotna myśl. Dzięki!
Paulj