Comment faire une requête Linq de regroupement sur des clés multiples en VB .Net ?

De ORSWiki
Aller à : navigation, rechercher
   ' En Visual Basic .Net, la syntaxe du regroupement sur des clés multiples 
   '  est aussi simple qu'en C# :
   Dim personnes() = { _
       New With {.Nom = "Pierre", .Masculin = True, .Pays = "France", .Capital = 10}, _
       New With {.Nom = "Paul", .Masculin = True, .Pays = "France", .Capital = 15}, _
       New With {.Nom = "Françoise", .Masculin = False, .Pays = "France", .Capital = 20}, _
       New With {.Nom = "John", .Masculin = True, .Pays = "Amerique", .Capital = 25}}
   Dim cumulCapitalParGenreEtPays = From personne In personnes _
       Group By personne.Masculin, personne.Pays _
       Into Group Select New With { _
           .Masculin = Masculin, _
           .Pays = Pays, _
           .CapitalParGenreEtPays = Group.Sum(Function(p) p.Capital), _
           .NbPersonnes = Group.Count()}
   Debug.WriteLine("Calcul juste :")
   For Each total In cumulCapitalParGenreEtPays
       Debug.WriteLine("Total " & _
           "Masculin=" & total.Masculin & " x " & _
           total.Pays & " : " & _
           total.CapitalParGenreEtPays & " (" & total.NbPersonnes & " personne(s))")
   Next
   ' Je ne sais pas si Visual Studio a été corrigé, mais avant (VB 2010 ou 2008 ?)
   '  ce n'était pas aussi simple :
   ' En Visual Basic .Net, la syntaxe du regroupement sur des clés multiples n'était pas aussi 
   '  intuitive qu'en C#, il fallait utiliser le mot clé Key au bon endroit, sinon le regroupement 
   '  ne se faisait pas :
   Dim cumulCapitalParGenreEtPays2 = From personne In personnes _
       Group By clef = New With {Key personne.Masculin, Key personne.Pays} _
       Into Group Select New With { _
           .Regroupement = clef, _
           .CapitalParGenreEtPays = Group.Sum(Function(p) p.Capital), _
           .NbPersonnes = Group.Count()}
   Debug.WriteLine("Calcul juste (2) :")
   For Each total In cumulCapitalParGenreEtPays2
       Debug.WriteLine("Total " & _
           "Masculin=" & total.Regroupement.Masculin & " x " & _
           total.Regroupement.Pays & " : " & _
           total.CapitalParGenreEtPays & " (" & total.NbPersonnes & " personne(s))")
   Next
   ' Sans utiliser le mot clé Key, c'est possible aussi, mais la syntaxe n'est pas aussi simple :
   Dim cumulCapitalParGenreEtPays3 = From personne In personnes _
       Group By clef = _
           New With {personne.Masculin}.Masculin, _
           New With {personne.Pays}.Pays _
       Into Group Select New With { _
           .Regroupement = clef, _
           .Pays = Pays, _
           .CapitalParGenreEtPays = Group.Sum(Function(p) p.Capital), _
           .NbPersonnes = Group.Count()}
   Debug.WriteLine("Calcul juste (3) :")
   For Each total In cumulCapitalParGenreEtPays3
       Debug.WriteLine("Total " & _
           "Masculin=" & total.Regroupement & " x " & _
           total.Pays & " : " & _
           total.CapitalParGenreEtPays & " (" & total.NbPersonnes & " personne(s))")
   Next
   ' Voici un exemple dans lequel le regroupement ne se fait pas :
   Dim cumulCapitalParGenreEtPays4 = From personne In personnes _
       Group By clef = New With {personne.Masculin, personne.Pays} _
       Into Group Select New With { _
           .Regroupement = clef, _
           .CapitalParGenreEtPays = Group.Sum(Function(p) p.Capital), _
           .NbPersonnes = Group.Count()}
   Debug.WriteLine("Calcul faux (pas de regroupement) :")
   For Each total In cumulCapitalParGenreEtPays4
       Debug.WriteLine("Total " & _
           "Masculin=" & total.Regroupement.Masculin & " x " & _
           total.Regroupement.Pays & " : " & _
           total.CapitalParGenreEtPays & " (" & total.NbPersonnes & " personne(s))")
   Next
   ' Résultats:
   ' Calcul juste
   ' Total Masculin=True x France : 25 (2 personne(s))
   ' Total Masculin=False x France : 20 (1 personne(s))
   ' Total Masculin=True x Amerique : 25 (1 personne(s))
   ' Calcul faux (pas de regroupement) :
   ' Total Masculin=True x France : 10 (1 personne(s))
   ' Total Masculin=True x France : 15 (1 personne(s))
   ' Total Masculin=False x France : 20 (1 personne(s))
   ' Total Masculin=True x Amerique : 25 (1 personne(s))
   ' Enfin, voici la syntaxe correcte avec les expressions Lambda (le résultat est le même) :
   Debug.WriteLine("Calcul juste (lambda) :")
   Dim cumulCapitalParGenreEtPaysLambda = personnes _
       .GroupBy(Function(personne) New With {Key personne.Masculin, Key personne.Pays}) _
       .Select(Function(regroupement) New With { _
           .Regroupement = regroupement.Key, _
           .NbPersonnes = regroupement.Count, _
           .CapitalParGenreEtPays = regroupement.Sum(Function(c) c.Capital)})
   For Each total In cumulCapitalParGenreEtPaysLambda
       Debug.WriteLine("Total " & _
           "Masculin=" & total.Regroupement.Masculin & " x " & _
           total.Regroupement.Pays & " : " & _
           total.CapitalParGenreEtPays & " (" & total.NbPersonnes & " personne(s))")
   Next