使用LINQ对DataTable中的数据进行分组

12

我想使用LINQ对DataTable中的数据进行分组(列:userid、chargetag、charge)。

内容可能如下所示:

userid    chargetag    charge
-----------------------------
user1     tag3         100
user2     tag3         100
user3     tag5         250

我需要得到这样的结果:

chargetag    count    sum
-------------------------
tag3         2        200
tag5         1        250

这是我目前为止的代码:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  let count = g.Count()
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = count,
                  };

我可以提取chargetag的名称和数量。如何更改LINQ查询以访问费用总和?

先行致谢 :-)

敬礼, Kevin

1个回答

44

这很简单 - 只需在组上使用 Sum 扩展方法即可。

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = g.Count(),
                      ChargeSum = g.Sum(x => x.Field<int>("charge"))
                  };

(我在这里删除了 let 子句,因为它并没有真正带来任何好处。)

现在这种方法可能是低效的;它可能会进行两次分组以执行两个聚合操作。如果您真的想要解决这个问题,可以像这样使用查询延续来修复:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  select new
                  {
                      ChargeTag = g.Key,
                      List = g.ToList(),
                  } into g
                  select new 
                  {
                      g.ChargeTag,
                      Count = g.List.Count,
                      ChargeSum = g.List.Sum(x => x.Field<int>("charge"))
                  };

或者使用 let 子句:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  let list = g.ToList()
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = list.Count,
                      ChargeSum = list.Sum(x => x.Field<int>("charge"))
                  };

很好的解释(像往常一样)。我很想知道第一个选项是否会进行两次分组,或者它是否会被优化。 - kjn
@Jon Skeet:有什么好方法可以帮助我掌握所有的LINQ知识吗?我有你的《C#深入》这本书,但是在LINQ部分(就像你上面的例子)我感到很困惑。其他编程内容还好。 - user153923
@jp2code:嗯,有很多关于LINQ的书籍...或者你可能会喜欢我的Edulinq博客系列:http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx - Jon Skeet
有人能给我VB的代码吗?我尝试了在线转换器,但是出现了错误“'Into' expected”。 - RookieAppler
@RookieAppler:我建议你阅读VB中使用LINQ进行分组的文档,而不是尝试转换器。如果你仍然遇到问题,请提出一个新问题,并详细说明你想要做什么以及你已经尝试了什么。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接