Reputation: 1840
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)?
Upvotes: 134
Views: 236594
Reputation: 3229
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.
Upvotes: 1
Reputation: 891
If you want the whole record,here is a lambda way:
var q = _context
.lasttraces
.GroupBy(s => s.AccountId)
.Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());
Upvotes: 54
Reputation: 421998
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();
Upvotes: 252
Reputation: 37633
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
Upvotes: 58
Reputation: 311
Go a simple way to do this :-
Created one class to hold following information
Go the list of sites stored on a ArrayList object. And executed following query to sort it in descending order by Level.
var query = from MyClass object in objCollection
orderby object.Level descending
select object
Once I got the collection sorted in descending order, I wrote following code to get the Object that comes as top row
MyClass topObject = query.FirstRow<MyClass>()
This worked like charm.
Upvotes: 3
Reputation: 48265
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) };
Upvotes: 6