tables multiple from different columns and .net linq group-by aggregate

.net - multiple - linq group by sum



Agrupar por columnas mĂșltiples (12)

Aunque esta pregunta es sobre las propiedades de grupo por clase, si desea agrupar por varias columnas contra un objeto ADO (como un DataTable), debe asignar sus elementos "nuevos" a las 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ómo puedo hacer GroupBy en múltiples columnas en LINQ

Algo similar a esto en SQL:

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

¿Cómo puedo convertir esto a 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


Desde C # 7 también puedes usar tuplas de valor:

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

o

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


Grupo x por nuevo {x.Col, x.Col}


Muestra procesal

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


Ok tengo esto como:

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


Para agrupar por columnas múltiples, intente esto en su lugar ...

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

De la misma manera puedes agregar Column3, Column4, etc.


También puede usar un Tuple <> para una agrupación fuertemente tipada.

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), }


Una cosa a tener en cuenta es que necesita enviar un objeto para expresiones Lambda y no puede usar una instancia para una clase.

Ejemplo:

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

Esto compilará pero generará una clave por ciclo .

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

Si no desea asignar un nombre a las propiedades clave y luego recuperarlas, puede hacerlo así. Esto lo hará GroupBy correctamente y le dará las propiedades clave.

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; }


Utilice un tipo anónimo.

P.ej

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


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


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


var Results= query.GroupBy(f => new { /* add members here */ });