我一直在讨论这个...我在内存中有一个表,这样的DataTable结构如下:
Input:
ID | Invoice | Account | Payment | Subtotal
-----------------------------------------------------------------
0 | 09310 | 123 | 6.0 | ?
-----------------------------------------------------------------
我希望使用Linq执行以下操作(我对Linq很新!)
对于同一帐户的每一行,将所有付款添加到一起并写入或更新小计字段 我不想折叠表,发票号码会有所不同。我的想法是,有两种方法可以做到这一点
(A)以所有记录的BLANK小计列开头...付款的值将一起添加,然后写入小计列
(B)创建表格时,我将付款值重复到小计字段中。之后,linq只需添加/替换同一列中的值
所以我们会忽略ID和Invoice字段;其帐户和小计(如果使用风格(A)也支付付款)
(A) Input: *(note that there are two records for 123)*
ID | Invoice | Account | Payment | Subtotal
-----------------------------------------------------------------
0 | 03310 | 123 | 6.0 |
-----------------------------------------------------------------
1 | 09728 | 123 | 4.0 |
-----------------------------------------------------------------
2 | 07731 | 559 | 18.0 |
-----------------------------------------------------------------
(B) Input:
ID | Invoice | Account | Payment | Subtotal
-----------------------------------------------------------------
0 | 03310 | 123 | 6.0 | 6.0
-----------------------------------------------------------------
1 | 09728 | 123 | 4.0 | 4.0
-----------------------------------------------------------------
2 | 07731 | 559 | 18.0 | 18.0
-----------------------------------------------------------------
Result:
ID | Invoice | Account | Payment | Subtotal
-----------------------------------------------------------------
0 | 03310 | 123 | 6.0 | 10.0
-----------------------------------------------------------------
1 | 09728 | 123 | 4.0 | 10.0
-----------------------------------------------------------------
2 | 07731 | 559 | 18.0 | 18.0
-----------------------------------------------------------------
因此,每个小计单元格将拥有每个唯一帐户的所有付款总额
我认为样式(B)会更容易,因为我们只需处理这两列
对于风格(B),我尝试过像
这样的东西rpTable.AsEnumerable().GroupBy(g => int.Parse(g.Field<string>("Account"))).Select(g => g.Sum(p => p.Field<decimal>("SubTotal")));
但是我可以告诉它遗漏了什么......嗯嗯
答案 0 :(得分:1)
使用Select,您不会更新表格。这只返回所选值的IEnumerable。
您要做的是将列添加到表中,然后填充它:
var subTotalByAccount = table.AsEnumerable()
.GroupBy(g => g.Field<string>("Account"))
.Select(g => new { Account = g.Key, SubTotal = g.Sum(p => p.Field<decimal>("Payment")) })
.ToDictionary(t => t.Account, t => t.SubTotal);
table.Columns.Add("SubTotal", typeof(decimal));
foreach (var row in table.AsEnumerable())
{
row.SetField(columnName: "SubTotal", value: subTotalByAccount[row.Field<string>("Account")]);
}
答案 1 :(得分:1)
非常感谢timcbaoth,是的,我同意你说的话。我试图提升您的帖子,但系统说我可能不会:-(
我用暴力来解决(下图),但我也会评估你的解决方案!再次感谢!!
var query = from row in rpTable.AsEnumerable()
group row by int.Parse(row.Field<string>("Account")) into grp
orderby grp.Key
select new
{
Id = grp.Key,
Sum = grp.Sum(r => r.Field<decimal>("Payment"))
};
foreach (var grp in query)
{
rpTable.Select("Account ="+grp.Id).ToList<DataRow>().ForEach(r=>r["Payment"] = grp.Sum);
}
答案 2 :(得分:-1)
我找到了一个阴险的小虫子,所以我是这样的:
OLD: rpTable.Select("Account ="+grp.Id).ToList<DataRow>().ForEach(r=>r["Payment"] = grp.Sum);
NEW: rpTable.Select("Account ='"+ grp.Id +"'").ToList<DataRow>().ForEach(r => r["Payment"] = grp.Sum);