2

I have an Entity with the following fields GUID TaskId, GUID SubTaskId, DateTime Timestamp

The TaskId may be one-to-many with the SubTaskId. It's like a composite key almost.

I would like to write an expression or expressions resulting in the newest among each TaskId i.e.

TaskId SubTaskId Timestamp
1 A 2010-11-22 15:48:49.727
1 B 2010-11-22 16:24:51.117
2 C 2010-11-15 11:49:05.717
2 D 2010-11-15 14:02:11.467

Would result in a sequence containing only:
TaskId SubTaskId Timestamp
1 B 2010-11-22 16:24:51.117
2 D 2010-11-15 14:02:11.467

This expression works just fine for showing all TaskId's and TimeStamps

var q1 = 
    from req in myEntity
    orderby req.TaskId
    select new
    {
        req.TaskId,
        req.SubTaskId,
        req.Timestamp
    };

but I would like to show only the latest Timestamp for each TaskId. All my attempts at adding a max to the expression fail. The posting (http://stackoverflow.com/questions/2034800/how-do-you-find-the-group-wise-max-in-linq) seemed close, but I couldn't translate it into something working. Perhaps a foreach is needed.

Blanthor
  • 2,568
  • 8
  • 48
  • 66

2 Answers2

2

How about this?

var q1 = 
    from req in myEntity
    group req by req.TaskId into g
    let topReq = g.OrderByDescending(r => r.Timestamp).FirstOrDefault()
    select new
    {
        topReq.TaskId,
        topReq.SubTaskId,
        topReq.Timestamp
    };
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
1
var tasks = new[] { 
new { TaskId = 1, SubTaskId = "A", Timestamp = DateTime.Parse("2010-11-22 15:48:49.727")},
new { TaskId = 1, SubTaskId = "B", Timestamp = DateTime.Parse("2010-11-22 16:24:51.117")},
new { TaskId = 2, SubTaskId = "C", Timestamp = DateTime.Parse("2010-11-15 11:49:05.717")},
new { TaskId = 2, SubTaskId = "D", Timestamp = DateTime.Parse("2010-11-15 14:02:11.467")}};


var newestTasks = 
    from task in tasks
    group task by task.TaskId into g
    select g.Where(t => t.Timestamp == g.Max(t2 => t2.Timestamp)).Single();

foreach (var task in newestTasks)
    Console.WriteLine("TaskId = {0}, SubTaskId = {1}, Timestamp = {2}", 
        task.TaskId, task.SubTaskId, task.Timestamp);
Richard Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
  • Nice. I like the way you put the test together. I'll be sure to construct the sequence like this next time I have a question in LINQ. This works quite well. – Blanthor Nov 30 '10 at 23:44
  • Alas, Single is not supported by LINQ to Entities, although your example, as it is, does work well. – Blanthor Nov 30 '10 at 23:52