Question

Comment puis-je faire GroupBy plusieurs colonnes dans LINQ

Quelque chose de semblable à cela dans SQL:

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

Comment puis-je convertir 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
Était-ce utile?

La solution

Utilisez un type anonyme.

Par exemple,

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

Autres conseils

échantillon de procédure

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

Ok a ce que:

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();

Pour le groupe par plusieurs colonnes, Essayez plutôt ...

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

Même façon que vous pouvez ajouter Colonne3, column4 etc.

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

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

ou

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

Vous pouvez également utiliser un tuple <> pour un groupe fortement typé.

from grouping in list.GroupBy(x => new Tuple<string,string,string>(x.Person.LastName,x.Person.FirstName,x.Person.MiddleName))
select new SummaryItem
{
    LastName = grouping.Key.Item1,
    FirstName = grouping.Key.Item2,
    MiddleName = grouping.Key.Item3,
    DayCount = grouping.Count(), 
    AmountBilled = grouping.Sum(x => x.Rate),
}

Bien que cette question pose sur le groupe par des propriétés de classe, si vous souhaitez regrouper plusieurs colonnes sur un objet ADO (comme un DataTable), vous devez affecter vos éléments « nouveaux » aux variables:

EnumerableRowCollection<DataRow> ClientProfiles = CurrentProfiles.AsEnumerable()
                        .Where(x => CheckProfileTypes.Contains(x.Field<object>(ProfileTypeField).ToString()));
// do other stuff, then check for dups...
                    var Dups = ClientProfiles.AsParallel()
                        .GroupBy(x => new { InterfaceID = x.Field<object>(InterfaceField).ToString(), ProfileType = x.Field<object>(ProfileTypeField).ToString() })
                        .Where(z => z.Count() > 1)
                        .Select(z => z);

C # 7.1 ou plus à l'aide et Tuples Inferred tuple element names:

// declarative query syntax
var result = 
    from x in table
    group x by (x.Column1, x.Column2) into g
    select (g.Key.Column1, g.Key.Column2, QuantitySum: g.Sum(x => x.Quantity));

// or method syntax
var result2 = table.GroupBy(x => (x.Column1, x.Column2))
    .Select(g => (g.Key.Column1, g.Key.Column2, QuantitySum: g.Sum(x => x.Quantity)));

C # 3 ou plus avec anonymous types:

// declarative query syntax
var result3 = 
    from x in table
    group x by new { x.Column1, x.Column2 } into g
    select new { g.Key.Column1, g.Key.Column2, QuantitySum = g.Sum(x => x.Quantity) };

// or method syntax
var result4 = table.GroupBy(x => new { x.Column1, x.Column2 })
    .Select(g => 
      new { g.Key.Column1, g.Key.Column2 , QuantitySum= g.Sum(x => x.Quantity) });
var Results= query.GroupBy(f => new { /* add members here */  });

.GroupBy(x => (x.MaterialID, x.ProductID))

.GroupBy(x => x.Column1 + " " + x.Column2)

groupe x par le nouveau {x.Col, x.Col}

Une chose à noter est que vous devez envoyer un objet pour les expressions lambda et ne peut pas utiliser une instance pour une classe.

Exemple:

public class Key
{
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }
}

compilera mais générera une clé par cycle .

var groupedCycles = cycles.GroupBy(x => new Key
{ 
  Prop1 = x.Column1, 
  Prop2 = x.Column2 
})

Si vous wan't pour nommer les principales propriétés, puis les retreive vous pouvez le faire comme ça à la place. Cela correctement et vous GroupBy donner les propriétés clés.

var groupedCycles = cycles.GroupBy(x => new 
{ 
  Prop1 = x.Column1, 
  Prop2= x.Column2 
})

foreach (var groupedCycle in groupedCycles)
{
    var key = new Key();
    key.Prop1 = groupedCycle.Key.Prop1;
    key.Prop2 = groupedCycle.Key.Prop2;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top