1069 votes

Regroupement par plusieurs colonnes

Comment puis-je faire un GroupBy sur plusieurs colonnes en LINQ ?

Quelque chose de similaire à cela en SQL :

SELECT * FROM <TableName> GROUP BY <Column1>,<Column2>

Comment puis-je convertir cela en LINQ :

QuantityBreakdown
(
    MaterialID int,
    ProductID int,
    Quantity float
)

INSERT INTO @QuantityBreakdown (MaterialID, ProductID, Quantity)
SELECT MaterialID, ProductID, SUM(Quantity)
FROM @Transactions
GROUP BY MaterialID, ProductID

1292voto

leppie Points 67289

Utilisez un type anonyme.

Par exemple,

group x by new { x.Column1, x.Column2 }

34 votes

Si vous n'êtes pas habitué à regrouper des types anonymes, l'utilisation du mot-clé "new" dans cet exemple suffit.

8 votes

Dans le cas d'un mvc avec nHibernate, obtenir une erreur pour des problèmes de dll. Problème résolu par GroupBy(x=> new { x.Column1, x.Column2 }, (key, group) => new { Key1 = key.Column1, Key2 = key.Column2 , Result = group.ToList() }) ;

0 votes

Je pensais que dans ce cas, les nouveaux objets seraient comparés par référence, donc pas de correspondance - pas de regroupement.

824voto

Mo0gles Points 2624

Echantillon de procédure :

.GroupBy(x => new { x.Column1, x.Column2 })

0 votes

Quel est le type de l'objet retourné ?

6 votes

@MGG_Soft ce serait un type anonyme.

0 votes

Ce code ne fonctionne pas pour moi : "Déclarateur de type anonyme non valide".

502voto

Sreedhar Points 6225

J'ai reçu ça comme :

var query = (from t in Transactions
             group t by new {t.MaterialID, t.ProductID}
             into grp
                    select new
                    {
                        grp.Key.MaterialID,
                        grp.Key.ProductID,
                        Quantity = grp.Sum(t => t.Quantity)
                    }).ToList();

81 votes

+1 - Merci pour cet exemple complet. Les extraits de l'autre réponse sont trop courts et sans contexte. Vous montrez également une fonction d'agrégation (Sum dans ce cas). C'est très utile. Je trouve que l'utilisation d'une fonction d'agrégation (c'est-à-dire MAX, MIN, SUM, etc.) en parallèle avec le regroupement est un scénario courant.

0 votes

Ici : stackoverflow.com/questions/14189537/ Dans le cas d'un tableau de données, le regroupement est basé sur une seule colonne, dont le nom est connu, mais comment faire si les colonnes sur lesquelles le regroupement doit être effectué doivent être générées dynamiquement ?

0 votes

Ceci est vraiment utile pour comprendre le concept de regroupement et l'application de l'agrégation sur celui-ci.

181voto

Milan Points 51

Pour grouper par plusieurs colonnes, essayez plutôt ceci...

GroupBy(x=> new { x.Column1, x.Column2 }, (key, group) => new 
{ 
  Key1 = key.Column1,
  Key2 = key.Column2,
  Result = group.ToList() 
});

De la même manière, vous pouvez ajouter Colonne3, Colonne4 etc.

4 votes

Cela a été très utile et devrait recevoir beaucoup plus de votes positifs ! Result contient tous les ensembles de données liés à toutes les colonnes. Nous vous remercions de votre attention.

1 votes

Note : j'ai dû utiliser .AsEnumerable() au lieu de ToList()

1 votes

Génial, merci pour cela. Voici mon exemple. Notez que GetFees renvoie un IQueryable<Fee> RegistryAccountDA.GetFees(registryAccountId, fromDate, toDate) .GroupBy(x => new { x.AccountId, x.FeeName }, (key, group) => new { AccountId = key.AccountId, FeeName = key.FeeName, AppliedFee = group.Sum(x => x.AppliedFee) ? ? 0M }).ToList() ;

47voto

Depuis C# 7, vous pouvez également utiliser des tuples de valeurs :

group x by (x.Column1, x.Column2)

ou

.GroupBy(x => (x.Column1, x.Column2))

2 votes

Je pense qu'il manque un ) à la fin. Vous ne fermez pas le ()

0 votes

Je l'ai ajouté.

2 votes

.GroupBy(x => new { x.Column1, x.Column2})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X