C # LINQ для объектов: помощь по группам / сумме - PullRequest
6 голосов
/ 05 июля 2010

В списке объектов транзакций я пытаюсь сгруппировать по BatchNo, а затем сложить суммы.

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

На этом этапе я перехожу в код, просматриваю окно локальных пользователей, чтобы увидеть, каков мой результатset - это проверка файла, который я импортировал в этот объект.

Последняя партия в файле имеет 3 записи, каждая из которых содержит 100 записей, которые просверливаются в объекте списка транзакций.Однако при детализации результата sGroup та же партия будет иметь общее количество 100 (должно быть 300).Что я запутал в этом запросе?

Обратите внимание, что я сохранил это как строку, так как мы заполнены нулями слева от поля из 8 символов.По соображениям экспорта я решил хранить в виде строки.Хотя это может (и, вероятно, будет) изменено, оно не отвечает на мой вопрос: как сделать так, чтобы этот запрос агрегировал сумму в наборы по BatchNo?

Ответы [ 2 ]

16 голосов
/ 05 июля 2010

Вам нужно позвонить Sum вместо 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
    };

Я бы также предложил, если ваше поле mAmount сохраненокак string, чтобы использовать более надежный метод, чем int.Parse (поскольку это вызовет исключение, если строка не является допустимым целым числом, например, если она пуста).Как то так:

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
    };
2 голосов
/ 05 июля 2010

Вместо того, чтобы делать макс, вы должны использовать сумму в вашей группе.Прямо сейчас вы устанавливаете для свойства только максимальное значение в объекте, сумма будет суммировать все значения в свойстве.

...