2010-09-30 19 views
9

Desidero utilizzare LINQ per raggruppare i dati da un DataTable (colonne: userid, chargetag, charge).Utilizzare LINQ per raggruppare i dati da DataTable

Il contenuto potrebbe essere la seguente:

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

ho bisogno di qualcosa di simile come risultato:

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

Questo è quello che ho finora:

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 può estrarre il nome del chargetag e il numero di esso. Come dovrei cambiare la query LINQ per accedere anche alla somma delle spese?

Grazie in anticipo :-)

saluti, Kevin

risposta

34

Questo è abbastanza semplice - basta usare il metodo Sum estensione sul gruppo.

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

(ho rimosso la clausola let qui perché non era davvero comprare nulla.)

Ora che possono essere inefficiente; potrebbe terminare il raggruppamento due volte per eseguire due operazioni di aggregazione. Si potrebbe rimediare come con una continuazione query come questa, se si voleva davvero:

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 clausola let invece:

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

bella spiegazione (come al solito). Sarei interessato a sapere se la prima opzione in realtà si raggruppa due volte o se viene ottimizzata. – kjn

+0

Funziona perfettamente (ovviamente ;-)) Grazie ancora! – bitfrickler

+0

@Jon Skeet: Qual è un buon modo per me di cogliere tutte queste cose LINQ? Ho il tuo libro 'C# In Depth', ma mi perdo nella sezione LINQ (come il tuo esempio sopra). Il resto della roba di codifica non è male. – jp2code

Problemi correlati