How to select only the records with the highest date in LINQ

Viewed 220195

I have a table, 'lasttraces', with the following fields.

Id, AccountId, Version, DownloadNo, Date

The data looks like this:

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

How can I, in LINQ to SQL, only get the last lasttrace of every AccountId (the one with the highest date)?

6 Answers

If you just want the last date for each account, you'd use this:

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

If you want the whole record:

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

Here is a simple way to do it

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

Also have a look this great LINQ place - LINQ to SQL Samples

It could be something like:

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

LINQ's .OrderByDescending().FirstOrDefault() approach is good. But the https://github.com/morelinq/MoreLINQ people do it better: .MaxBy()

Example:

IEnumerable<Person> data = Data.GetPersons();
Person oldestPerson = data.MaxBy(p => p.Age);

Or in the latest version of MoreLINQ, they have changed the return type:

IEnumerable<Person> data = Data.GetPersons();
IEnumerable<Person> oldestPersons = data.MaxBy(p => p.Age);
Person oldestPerson = oldestPersons.First();

So what used to be .MaxBy() is now .MaxBy().First(). This has the advantage that you can handle more than 1 result (used to be only the first person with the max age, but there may be more persons with the same age). Another advantage is that .MaxBy() can now handle an empty IEnumerable<T> without throwing an exception. Of course, the exception occurs in .First() then, but you can decide to use .FirstOrDefault() instead to avoid this.

Related