2010-11-30 7 views
2

J'ai une entité avec les champs suivants GUID taskId, GUID SubTaskId, DateTime TimestampComment obtenir l'horodatage max et GroupBy un autre champ dans LINQ to Entities

TaskId peut être un à plusieurs avec le SubTaskId. C'est comme une clé composite presque.

Je souhaite écrire une expression ou expressions résultant dans le plus récent parmi chaque TaskId ie

TaskId SubTaskId Horodatage
1 A 22/11/2010 15: 48: 49,727
1 B 22/11/2010 16: 24: 51,117
2 C 15/11/2010 11: 49: 05,717
2 D 15/11/2010 14: 02: 11,467

se traduirait par une séquence ne contenant que:

TaskId SubTaskId Horodatage 1 B 22/11/2010 16: 24: 51,117
2 D 15/11/2010 14: 02: 11,467

Cette expression fonctionne très bien pour montrer de tous TaskId et TimeStamps

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

mais je voudrais montrer que le dernier Tim estamp pour chaque TaskId. Toutes mes tentatives d'ajout d'un maximum à l'expression échouent. L'affichage (http://stackoverflow.com/questions/2034800/how-do-you-find-the-group-wise-max-in-linq) semblait proche, mais je ne pouvais pas le traduire en quelque chose de fonctionnel. Peut-être qu'un foreach est nécessaire.

Répondre

2

Que pensez-vous de cela?

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 
    }; 
+0

Excellentissime! Merci. – Blanthor

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); 
+0

Nice. J'aime la façon dont vous mettez le test ensemble. Je vais être sûr de construire la séquence comme ça la prochaine fois que j'ai une question dans LINQ. Cela fonctionne très bien. – Blanthor

+0

Hélas, Single n'est pas supporté par LINQ to Entities, bien que votre exemple, tel qu'il est, fonctionne bien. – Blanthor