2012-05-22 2 views
2

Linq noob здесь. Как это исправить?Linq - Группировка с расчетами суммы

   var result = (from row in rulestable.AsEnumerable() 
         let sup = row.Field<int>("Supplier") 
         let amo = row.Field<decimal>("Amount") 
         let adv = row.Field<decimal>("Advance") 
         let bal = row.Field<decimal>("Balance") 
         let vat = row.Field<decimal>("VatRate") 
         group row by new { sup, vat } into grp 
         select new 
         { 
          Supplier = grp.Key.sup, 
          Amount = grp.Sum(grp => grp["amo"]), 
          Advance = grp.Sum(grp => grp["adv"]), 
          Balance = grp.Sum(grp => grp["bal"]), 
          VatRate = grp.Key.vat 
         }).ToList(); 

Я хочу сгруппировать свой «управляемый» массив данных на 2 столбцах, Поставщике и VatRate. Сумма, аванс и баланс результата должны быть установлены на сумму всех столбцов, которые были сгруппированы.

Я получаю сообщение об ошибке - «аргументы типа не могут быть выведены из использования» на grp.Sum. Тем не менее, я думаю, что это выражение неверно - я думаю, что он будет суммировать столбцы результатов, а не исходные столбцы, как я хочу.

Пример:

Входной DataTable:
Поставщик, Сумма, заранее, баланс, VatRate
S1, 10, 5, 5, 1
S1, 10, 5, 5, 1

Ожидаемые результаты:
S1, 20, 10, 10, 1


Каков наилучший способ сделать это?

ответ

4

Внутри лямбда, grp (который я переименовал r для строки, чтобы отличить от самой группы) будет DataRow. Компилятор не знает, какой тип данных grp [string] возвращается, поскольку он просто возвращает object. Попробуйте это:

DataTable rulestable = new DataTable(); 
rulestable.Columns.Add("Supplier"); 
rulestable.Columns.Add("Amount", typeof(decimal)); 
rulestable.Columns.Add("Advance", typeof(decimal)); 
rulestable.Columns.Add("Balance", typeof(decimal)); 
rulestable.Columns.Add("VatRate", typeof(decimal)); 
rulestable.Rows.Add("S1", 10M, 5M, 5M, 1M); 
rulestable.Rows.Add("S1", 10M, 5M, 5M, 1M); 

var result = (from row in rulestable.AsEnumerable() 
       let sup = row.Field<string>("Supplier") 
       let amo = row.Field<decimal>("Amount") 
       let adv = row.Field<decimal>("Advance") 
       let bal = row.Field<decimal>("Balance") 
       let vat = row.Field<decimal>("VatRate") 
       group row by new { sup, vat } into grp 
       select new 
       { 
        Supplier = grp.Key.sup, 
        Amount = grp.Sum(r => r.Field<decimal>("Amount")), 
        Advance = grp.Sum(r => r.Field<decimal>("Advance")), 
        Balance = grp.Sum(r => r.Field<decimal>("Balance")), 
        VatRate = grp.Key.vat 
       }).ToList(); 
 
Input: 
Supplier | Amount | Advance | Balance | VatRate 
----------------------------------------------- 
    S1 | 10 | 5 | 5 | 1 
----------------------------------------------- 
    S1 | 10 | 5 | 5 | 1 

Result: 
Supplier | Amount | Advance | Balance | VatRate 
----------------------------------------------- 
    S1 | 20 | 10 | 10 | 1 

Используя вход вы в комплекте поставки, это дает вам результат выше.

+0

Ну, это не показывает никаких ошибок intellisense. Это хорошо. Правильно ли это: Amount = grp.Sum (g => (десятичный) g ["amo"])? – Kev

+0

Да, они оба работают в LinqPad для меня. – akatakritos

+0

(десятичный) g ["amo"] завершится неудачно, потому что "amo" не является именем одного из столбцов в исходной таблице. – akatakritos

0

Когда я запускаю этот запрос, я потерпел неудачу в визуальной студии. В разделе «Поиск» было найдено следующее и хорошо работает в моей системе.

var result = (from row in rulestable.AsEnumerable() 
      group row by new {sup= row.Field<string>("Supplier"), 
           vat=row.Field<decimal>("VatRate")} into grp = Group 
      select new With 
      {.Supplier = sup, 
       .Amount = grp.Sum(r => r.Field<decimal>("Amount")), 
       .Advance = grp.Sum(r => r.Field<decimal>("Advance")), 
       .Balance = grp.Sum(r => r.Field<decimal>("Balance")), 
       .VatRate = vat 
       } 
      ).ToList(); 
+0

Лучше объявить структуру для итерации результата в нормальном режиме – Girichandran

Смежные вопросы