我有DataTable这样的
ProductId CountThisWeek CountLastWeek
1 10.0 15.0
1 20.0 5.0
2 5.0 10.0
2 DBNull 15.0
2 10.0 DBNull
3 DBNull 15.0
3 DBNull 15.0
我需要通过“压缩”(sum by productId)获取一个新的DataTable(或者,如果不是,至少是一个匿名数据结构,如字典),我的初始DataTable,如下所示:
ProductId CountThisWeek CountLastWeek
1 30.0 20.0
2 15.0 25.0
3 DBNull 30.0
规则很简单:DBNull + Value = Value,DBNull + DBNull = DBNull
我尝试实现这种聚合,如下所示:
(from row in table.AsEnumerable()
group row by row.Field<int>("ProductId") into g
select g).ToDictionary(
g => g.Key,
g => new {
CountThisWeek = g.Sum(r => row.Field<decimal>("CountThisWeek")),
CountLastWeek = g.Sum(r => row.Field<decimal>("CountLastWeek"))
}
但是这个Sum没有考虑我的DBNull规则...
我无法用可空的十进制做到这一点?
g.Sum(r => r.Field<decimal?>("CountThisWeek")),
所以,也许我需要做一些像
这样的事情g.Aggregate((summRow, nextRow) => {
DataRow dr = summRow.Table.NewRow();
decimal? sum = summRow.Field<decimal?>("CountThisWeek");
decimal? next = nextRow.Field<decimal?>("CountThisWeek");
decimal? result = (!sum.HasValue && !next.HasValue) ?
(decimal?)null : sum ?? 0 + next ?? 0;
dr["CountThisWeek"] = result;
return dr;
}),
这是实现我尝试的最佳方式吗?
我想在集合函数中获取decimal?
而不是DataRow
...
答案 0 :(得分:2)
你可以尝试
(from row in table.AsEnumerable()
group r by r.Field<int>("ProductId") into g
select g).ToDictionary(
g => g.Key,
g => new {
CountThisWeek = g.All(r => r.IsNull("CountThisWeek")) ?
null :
(decimal?)g.Sum(r => r.Field<decimal>("CountThisWeek")),
CountLastWeek = g.All(r => r.IsNull("CountLastWeek")) ?
null :
(decimal?)g.Sum(r => r.Field<decimal>("CountLastWeek"))
}
答案 1 :(得分:1)
您可以尝试这样的Aggregate
function with Accumulator
g.Aggregate((decimal?)null,(summRow, nextRow) =>
nextRow.IsNull("CountThisWeek")?
summRow:
((summRow??0) + nextRow.Field<decimal>("CountThisWeek"))
),