Linq: Come trasformare righe da colonne con un conteggio (dati campi incrociati)?
Domanda
Credo di aver bisogno di un modo per eseguire un perno o campi incrociati utilizzando C # e LINQ con un numero indeterminato di colonne. Tuttavia, vorrei aggiungere qualche dettaglio cominciando a vedere dove va.
Immaginate una tabella che ha due campi:
string EventName;
Datetime WhenItHappend;
Vogliamo generare un rapporto, come nell'esempio qui sotto dove abbiamo gruppo dal EventName, poi abbiamo una serie di colonne che calcolano una data e l'ora conteggio dei fotogrammi. La difficoltà è ovviamente un numero variabile di colonne.
Sport Gennaio 2010 Jan 2009 Feb 2010 Feb 2009
Basket 26 18 23 16
Hockey 28 19 25 18
Nuoto 52 45 48 43
Il cliente può creare qualsiasi numero di segnalini evento denominato per un report. Le funzioni sono sempre le stesse: "Nome", "begin", "fine"
.Un modo per montare questo come un risultato IQueryable singolo LINQ in C #?
Per quanto SQL va, ho provato a generare una tabella di date {TimeFrameName, inizio, fine} e unito che al tavolo sopra dove cominciare <= whenItHappened e whenItHappened <= fine, che ha prodotto un bel set di {EventName, TimeFrameName} poi ha fatto un conteggio (*), ma era ancora a sinistra con il modo di trasformare i dati, rendendo le righe per colonne.
Soluzione
Si dispone di una fila di classe / SQL
class Thing
{
public string EventName;
public DateTime WhenItHappend;
}
e si desidera eseguire il raggruppamento EventName e WhenItHappened.Month
// make a collection and add some Things to it
var list = new List<Thing>();
list.Add(new Thing(){ .... });
// etc
var groups = list.GroupBy(t => new { t.WhenItHappend.Month, t.EventName } );
Ora avete essenzialmente un array bidimensionale 2 di collezioni. È possibile scorrere questi su Mese / EventName per ottenere i conteggi degli elementi in ogni collezione, che è ciò che si desidera visualizzare nella tabella.
foreach (var row in groups.GroupBy(g => g.Key.EventName))
{
foreach (var month in row.GroupBy(g => g.Key.Month))
{
var value = month.Count();
}
}
L'operatore GroupBy restituisce un insieme di gruppi, dove ogni gruppo contiene una chiave e un sottoinsieme della lista originale che corrisponde alla chiave specificata. Se si specifica una chiave dimensionale 2, è possibile trattare il risultato come un array bidimensionale 2 di collezioni.
GroupBy è un operatore molto potente!