Linq - 用和计算分组

时间:2012-05-22 12:00:43

标签: c# linq

Linq noob在这里。我该如何纠正?

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

我想将我的数据表“rulestable”分组到2列,即Supplier和VatRate。结果的金额,预付款和余额必须设置为任何列分组的总和。

我收到错误 - “无法从grp.Sum上的用法推断出类型参数”。但是,我认为这个表达式都是错误的 - 我认为它会将结果列和我想要的源列相加。

示例:

输入数据表:
供应商,金额,预付款,余额,VatRate
S1,10,5,5,1 S1,10,5,5,1,

预期产量:
S1,20,10,10,1


最好的方法是什么?

2 个答案:

答案 0 :(得分: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

使用您提供的输入,可以得到您预期的结果。

答案 1 :(得分: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();