Group by dans LINQ : comprendre le regroupement avec des exemples concrets
\n\nSi vous avez déjà écrit des requêtes sur des collections en C#, vous avez sûrement rencontré la question : « Comment puis-je regrouper des données ? ». Le sujet group by in LINQ est l’un des plus populaires sur Stack Overflow (des dizaines de milliers de vues). Et ce n’est pas un hasard : le regroupement semble simple seulement à première vue. En réalité, les débutants butent sur des pièges typiques : comment sélectionner le premier enregistrement dans un groupe, comment calculer une somme ou faire un regroupement imbriqué.
\n\nDans cet article, nous allons analyser les 5 questions les plus fréquentes sur LINQ GroupBy et donner des réponses qui fonctionnent. C’est parti !
\n\n1. Comment fonctionne GroupBy dans LINQ ? Syntaxe de base
\n\nLa méthode GroupBy est l’équivalent de l’opérateur SQL GROUP BY. Elle divise une séquence en groupes selon une clé donnée. Le résultat est une collection d’objets IGrouping<TKey, TElement>, où chaque objet contient la clé et tous les éléments appartenant à ce groupe.
Voici un exemple très simple. Supposons que nous ayons une liste d’étudiants :
\n\npublic class Student\n{\n public string Name { get; set; }\n public string Group { get; set; }\n public int Score { get; set; }\n}\n\nvar students = new List<Student>\n{\n new Student { Name = "Anna", Group = "A", Score = 85 },\n new Student { Name = "Boris", Group = "B", Score = 90 },\n new Student { Name = "Vika", Group = "A", Score = 78 },\n new Student { Name = "Gleb", Group = "B", Score = 92 }\n};\n\nRegroupons par nom de groupe :
\n\nvar grouped = students.GroupBy(s => s.Group);\n\nforeach (var group in grouped)\n{\n Console.WriteLine($"Groupe : {group.Key}");\n foreach (var student in group)\n {\n Console.WriteLine($" {student.Name} — {student.Score}");\n }\n}\n\nRésultat :
\nGroupe : A\n Anna — 85\n Vika — 78\nGroupe : B\n Boris — 90\n Gleb — 92\n\nTout est simple. Mais le diable, comme toujours, se cache dans les détails.
\n\n2. Comment sélectionner le premier enregistrement de chaque groupe ?
\n\nC’est la question la plus fréquente sur group by in LINQ. Supposons que nous devions obtenir le meilleur étudiant de chaque groupe (avec le score maximum). Comment faire ?
\n\nLa solution — combiner GroupBy avec First() ou OrderByDescending :
var bestStudents = students\n .GroupBy(s => s.Group)\n .Select(g => g.OrderByDescending(s => s.Score).First());\n\nforeach (var student in bestStudents)\n{\n Console.WriteLine($"{student.Name} — {student.Group} — {student.Score}");\n}\n\nRésultat : Anna (85) et Gleb (92). Notez : à l’intérieur de Select, nous trions le groupe et prenons le premier élément. C’est la réponse à la question « comment faire LINQ group by first ».
Important : First() lèvera une exception si le groupe est vide. Si cela est possible — utilisez FirstOrDefault().
3. Comment calculer la somme, le nombre ou la moyenne par groupe ?
\n\nAprès un regroupement, il est souvent nécessaire non seulement de parcourir les éléments, mais aussi d’obtenir des valeurs agrégées. Par exemple, la somme des scores par groupe ou la moyenne des scores.
\n\nUtilisons Sum, Count, Average :
var groupStats = students\n .GroupBy(s => s.Group)\n .Select(g => new\n {\n Group = g.Key,\n Count = g.Count(),\n TotalScore = g.Sum(s => s.Score),\n AverageScore = g.Average(s => s.Score)\n });\n\nforeach (var stat in groupStats)\n{\n Console.WriteLine($"Groupe {stat.Group}: {stat.Count} étudiants, somme {stat.TotalScore}, moyenne {stat.AverageScore:F2}");\n}\n\nRésultat :
\nGroupe A: 2 étudiants, somme 163, moyenne 81.50\nGroupe B: 2 étudiants, somme 182, moyenne 91.00\n\nOn peut aussi utiliser Min et Max — dans