2010-07-04 14 views
6

Na liście obiektów transakcji próbuję grupować według BatchNo, a następnie sumować kwoty.C# LINQ do obiektów: Group By/Sum help

public class Extract 
{ 
    // Notable fields in TRANSACTION are: String mBatchNo, String mAmount 
    private List<Transaction> Transactions; 

    public void testTransactions() 
    { 

     // Sum of amounts grouped by batch number 
     var sGroup = from t in Transactions 
        group t by t.mBatchNo into g 
        select new { batchNo = g.Key, 
            totalAmount = g.Max(a => (Int32.Parse(a.mAmount)))}; 
    } 
} 

W tym momencie ja krok do spojrzenia przez okno kodu mieszkańcami, aby zobaczyć, co mój zestaw wyników jest sprawdzenie przed pliku mam importowanego do tego obiektu.

Ostatnia partia w pliku ma 3 rekordy, po 100 sztuk, z których można zobaczyć wiercenia w obiekcie listy transakcji. Jednak przewieranie w dół do wyniku sGroup znajduje tę samą partię, która ma 100 sumy (powinno być 300). Co pomieszałem w tym zapytaniu?

Pamiętaj, że zapisałem to jako ciąg znaków, ponieważ jesteśmy wypełnieni po lewej stronie pola 8-znakowego. Z przyczyn eksportowych postanowiłem przechowywać jako ciąg. Chociaż może to (i prawdopodobnie zostanie) zmienione, nie odpowiada na moje pytanie: jak sprawić, by to zapytanie agregowało sumę w zbiory według BatchNo?

Odpowiedz

16

Trzeba zadzwonić Sum zamiast Max:

var sGroup = from t in Transactions 
    group t by t.mBatchNo into g 
    select new { 
     batchNo = g.Key, 
     totalAmount = g.Sum(a => (int.Parse(a.mAmount))) // Sum, not Max 
    }; 

Chciałbym również zasugerować, jeśli pole mAmount jest przechowywana jako string, aby korzystać z bardziej wydajny sposób niż int.Parse (ponieważ to będzie wyjątek jeśli ciąg nie jest prawidłową liczbą całkowitą, np. jeśli jest pusty). Coś takiego:

int ParseOrZero(string text) 
{ 
    int value; 
    if (int.TryParse(text, out value)) 
     return value; 
    else 
     return 0; 
} 

var sGroup = from t in Transactions 
    group t by t.mBatchNo into g 
    select new { 
     batchNo = g.Key, 
     totalAmount = g.Sum(ParseOrZero) // blanks will be treated as 0 
    }; 
+0

Wow, to był weekend dla mnie! Dziękujemy za wejście do wyjątku! – Mohgeroth

2

Zamiast robić maksimum powinieneś używać sumy na swojej grupie. W tej chwili tylko ustawiasz właściwość na maksymalną wartość w obiekcie, suma zsumuje wszystkie wartości we właściwości.