J'ai une liste avec:
EMP_ID | UPDATED_DATE | MARK ------ | ------------ | ---- 111 | 01/01/2015 | 99 111 | 01/01/2013 | 85 111 | 01/01/2017 | 80 222 | 01/01/2011 | 70 222 | 01/01/2015 | 55 222 | 01/01/2002 | 60
Je dois sélectionner une ligne pour chaque ID, avec le dernier UPDATED_DATE, Dans notre etc:
EMP_ID | UPDATED_DATE | MARK ------ | ------------ | ---- 111 | 01/01/2017 | 80 222 | 01/01/2015 | 55
C'est le code de commande:
empMarksList.OrderBy(x=>x.EMP_ID).ThenBy(y=>y.UPDATED_DATE)
Utilisez GroupBy
:
var items = empMarksList
.GroupBy(e => e.EMP_ID)
.Select(grp => grp.OrderByDescending(v => v.UPDATED_DATE).First());
Ou si vous voulez un dictionnaire:
var dict = empMarksList
.GroupBy(e => e.EMP_ID)
.ToDictionary(grp => grp.Key,
grp => grp.OrderByDescending(v => v.UPDATED_DATE).First());
Une autre option est:
var items = context.EmpMarks
.GroupBy(e => e.EMP_ID, (k, g) => g
.FirstOrDefault(e => g.Max(v => v.UPDATED_DATE) == e.UPDATED_DATE));
Ce qui devrait générer GROUP BY
en SQL.
Je préfère cette variante, mais c'est la même chose que la réponse d'Amir:
var query =
empMarksList
.GroupBy(x => x.EMP_ID)
.SelectMany(x => x.OrderByDescending(y => y.UPDATED_DATE).Take(1));
Vous pouvez utiliser quelque chose comme ceci:
var result = empMarksList.GroupBy(x => x.Id)
.Select(g =>
g.Aggregate((a, x) => a == null || a.UPDATRED_DATE < x.UPDATRED_DATE ? x : a));
C'est un peu plus lourd que d'utiliser OrderBy
, mais de cette façon, vous ne pourrez pas commander toutes les sous-collections, ce qui est un peu excessif ici et utilise plus de ressources.
EDIT: Après une réponse de @arekzyla, je me suis rendu compte que mon option pourrait aussi être écrite comme suit:
var items = empMarksList.GroupBy(
x => x.Id,
(k, g) => g.Aggregate((a, x) => a == null || a.UPDATRED_DATE < x.UPDATRED_DATE ? x : a));
Il est moins lisible, mais il aura une procédure pas à pas pour deux collections, ce qui est négligeable dans la plupart des cas.
Je ne sais pas dans quel cas le code SQL généré serait plus optimal, donc il pourrait être intéressant de le vérifier.