2012-05-22 200 views
2

Linq noob here。我该如何纠正?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(); 

我想将我的datatable“rulestable”分组在2列Supplier和VatRate上。结果的金额,提前和结余必须设置为分组的任何列的总和。

我得到一个错误 - “类型参数无法从grp.Sum的用法推断”。但是,我认为这个表达式是错误的 - 我认为它会对结果列进行求和,而不是像我想要的那样对源列进行求和。

实施例:

输入数据表:
供应商,数量,超前,平衡,VatRate
S1,10,5,5,1
S1,10,5,5,1

预期输出:
S1,20,10,10,1


什么是最好的方法来做到这一点?

回答

4

在lambda里面,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 =>(decimal)g [“amo”])? – Kev

+0

是的,他们都似乎在LinqPad为我工作。 – akatakritos

+0

(十进制)g [“amo”]将失败,因为“amo”不是原始表中某列的名称。 – akatakritos

0

当我运行这个查询时,我在Visual Studio中失败了。在更多的搜索发现以下,并在我的系统中运行良好。

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