2016-07-25 7 views
0

Ich habe ein großes Dataset und ich versuche, dieses Dataset durch eine Reihe von Feldern zu gruppieren. In diesem Datensatz habe ich Zeilen (von Salden) für 5 aufeinander folgende Daten. Mein Ziel ist es, eine Liste von benutzerdefinierten Objekten zurückzugeben, die ein IDictionary-Feld mit Key als Datum und Balance als Wert haben. Ich habe versucht, etwas wie:LINQ zum Gruppieren einer Liste und zum Zurückgeben einer Liste von benutzerdefinierten Objekten, die ein eingebettetes Wörterbuch enthält

int[] DT = new int[] {20160725,20160726,20160727,20160728,20160729}; 
var tranformedData = 
posData 
.GroupBy(p => new {p.Symbol, p.Account}) 
.Select(gp => new TPosModel { 
    Symbol = gp.Key.Symbol, 
    Account = gp.Key.Account, 
    Balances = new Dictionary<int, decimal>{ 
    { 
     gp.Where(gpi => gpi.BusDate == DT[0]).Select(gpi => gpi.BusDate), 
     gp.Where(gpi => gpi.BusDate == DT[0]).Select(gpi => gpi.Balance) 
    }, 
    { 
     gp.Where(gpi => gpi.BusDate == DT[1]).Select(gpi => gpi.BusDate), 
     gp.Where(gpi => gpi.BusDate == DT[1]).Select(gpi => gpi.Balance) 
    }, 
    . 
    . 
    . 
} 

Dieser Code verursacht einen doppelten Schlüsselfehler. Ich habe das geschafft, indem ich das Wörterbuch in eine Tupelliste umwandelte, aber das ist nicht das gewünschte Endergebnis. Jeder hat einen Vorschlag, wie Sie dies bitte erreichen können.

Dank

+0

Können Sie die Eingabeklasse anzeigen? Auch die 'TPosModel' Klasse? –

+0

@YacoubMassad, Eingabe wird aus einer flachen Datei gelesen und hat die Form: 'List ({Symbol =" ABC.D ", Account =" 1234-0C ", BusDate = 20160725, Balance = 123,45}, {Symbol = "ABC.D", Konto = "1234-0C", BusDate = 20160726, Kontostand = 125,67}, {Symbol = "BCD.E", Konto = "2345-0D", BusDate = 20160725, Kontostand = -2300.5}, {Symbol = "BCD.E", Konto = "2345-0D", BusDate = 20160726, Balance = -2350.5}) ' Diese Liste muss konvertiert werden in: ' List ({Symbol = "ABC.D") , Konto = "1234-0C", Guthaben = {[20160725,123.45], [20160726,125.67]}}, {Symbol = "BCD.E", Konto = "2345-0D", Guthaben = {[20160725, - 2300.5] [20160726, -2350.5]}}) ' – skoppisetti

Antwort

1

Es sieht aus wie Sie auf dem BusDate durch eine interne Gruppe tun müssen, nachdem Sie eine herauszufiltern, die nicht in DT sind und dann müssen Sie die Balance aggregieren. Sie könnten Sum verwenden, wie ich hier habe oder etwas anderes wie First().Balance. Es hängt nur davon ab, wie Sie mehrere Salden am selben Tag behandeln möchten.

int[] DT = new int[] {20160725,20160726,20160727,20160728,20160729}; 
var tranformedData = 
posData 
.GroupBy(p => new {p.Symbol, p.Account}) 
.Select(gp => new TPosModel { 
    Symbol = gp.Key.Symbol, 
    Account = gp.Key.Account, 
    Balances = gp.Where(gpi => DT.Contians(gpi.BusDate)) 
       .GroupBy(gpi => gpi.BusDate) 
       .ToDictionary(g => g.Key, g => g.Sum(x => x.Balance) 
    }); 

Als Seite beachten Sie Sie Termine als DateTime statt int speichern möchten.

+0

Danke das scheint zu funktionieren. Dies ist, was ich getan habe: '... Balances = gp.Where (GPI => DT.Contains (gpi.BusDate)) .GroupBy (GPI => gpi.BusDate) .ToDictionary (g => g .Key, g => g.FirstOrDefault(). Balance) ' Ich bekomme eine Warnung für mögliche Nullreferenz bei' g.FirstOrDefault() '. Ich werde ein bisschen mehr testen und als gelöst markieren. – skoppisetti

+1

@skoppisetti Eigentlich könntest du einfach 'First' verwenden, da garantiert wird, dass die Gruppierungen mindestens einen Gegenstand haben' g => g.First(). Balance'. – juharr

Verwandte Themen