2010-09-30 55 views
9

Quiero usar LINQ para agrupar datos de una DataTable (columns: userid, chargetag, charge).Usar LINQ para agrupar datos de DataTable

El contenido podría tener este aspecto:

userid chargetag charge 
----------------------------- 
user1  tag3   100 
user2  tag3   100 
user3  tag5   250 

necesito algo como esto como resultado:

chargetag count sum 
------------------------- 
tag3   2  200 
tag5   1  250 

Esto es lo que tengo hasta ahora:

var groupedData = from b in dataTable.AsEnumerable() 
        group b by b.Field<string>("chargetag") into g 
        let count = g.Count() 
        select new 
        { 
         ChargeTag = g.Key, 
         Count = count, 
        }; 

I puede extraer el nombre de la etiqueta de carga y el número de la misma. ¿Cómo tendría que cambiar la consulta LINQ para acceder a la suma de los cargos también?

Gracias de antemano :-)

Saludos, Kevin

Respuesta

34

Eso es bastante fácil - sólo tiene que utilizar el método Sum extensión en el grupo.

var groupedData = from b in dataTable.AsEnumerable() 
        group b by b.Field<string>("chargetag") into g 
        select new 
        { 
         ChargeTag = g.Key, 
         Count = g.Count(), 
         ChargeSum = g.Sum(x => x.Field<int>("charge")) 
        }; 

(He quitado la cláusula let aquí, ya que no era realmente que comprar nada.)

Ahora que puede ser ineficiente; puede terminar agrupando dos veces para realizar dos operaciones de agregación. Usted podría arreglar que al igual que con una continuación consulta como esta, si realmente quería:

var groupedData = from b in dataTable.AsEnumerable() 
        group b by b.Field<string>("chargetag") into g 
        select new 
        { 
         ChargeTag = g.Key, 
         List = g.ToList(), 
        } into g 
        select new 
        { 
         g.ChargeTag, 
         Count = g.List.Count, 
         ChargeSum = g.List.Sum(x => x.Field<int>("charge")) 
        }; 

O con una cláusula let lugar:

var groupedData = from b in dataTable.AsEnumerable() 
        group b by b.Field<string>("chargetag") into g 
        let list = g.ToList() 
        select new 
        { 
         ChargeTag = g.Key, 
         Count = list.Count, 
         ChargeSum = list.Sum(x => x.Field<int>("charge")) 
        }; 
+0

buena explicación (como de costumbre). Me interesaría saber si la primera opción realmente se agrupa dos veces o si se optimiza. – kjn

+0

Funciona perfectamente (por supuesto ;-)) Gracias de nuevo! – bitfrickler

+0

@Jon Skeet: ¿Cuál es una buena forma de entender todo este LINQ? Tengo tu libro 'C# In Depth', pero me pierdo en la sección LINQ (como en tu ejemplo anterior). El resto de la codificación no es tan malo. – jp2code