我有一张这样的表:
Code | BuildDate | BuildQuantity
---------------------------------
1 | 2013-04-10 | 4
1 | 2014-09-23 | 1
1 | 2014-08-20 | 2
7 | 2014-02-05 | 4
我希望LINQ查询获取每个代码的最新构建日期,为该代码选择BuildQuantity,依此类推所有记录,并总结它。因此,对于上述数据,结果应为1 + 4 = 5
。
这就是我正在尝试的:
var built = (from tb in db.Builds
orderby tb.BuildDate descending
group tb by tb.Code into tbgrp
select tbgrp.Sum(c => c.BuildQuantity)).First();
此查询返回7 ...我做错了什么?
答案 0 :(得分:8)
在你拿第一个代码之前,你总结了所有代码的BuildQuantities,而不是你想要的第一个。
int built = db.Builds
.GroupBy(b => b.Code)
.Sum(g => g.OrderByDescending(b => b.BuildDate).First().BuildQuantity);
答案 1 :(得分:3)
您正在寻找每个代码的最后一个条目的构建数量的总和。您目前在分组之前订购,实际上并没有做任何事情(在分组之后,订单未定义)
首先,您希望通过代码获取最新元素。让小组先。通过扩展方法写作更加舒服:
IGrouping<int, Build> grouped = db.Builds.GroupBy(tb => tb.Code)
我们现在将元素分组。从每个组中,我们希望得到按生成日期降序排序的第一个元素。
var firsts = grouped.Select(gr => gr.OrderByDescending(gr => gr.BuildDate)
.First())
最后,我们可以得到总和:
var sum = firsts.Sum(tb => tb.BuildQuantity);
将这一切插入一起变成
var sum = db.Builds.GroupBy(tb => tb.Code).
.Select(gr => gr.OrderByDescending(gr => gr.BuildDate).First())
.Sum(tb => tb.BuildQuantity);
分组依据具有重载功能,允许您滚动组中的几乎所有内容。
如果您喜欢紧凑型代码,可以编写
var sum = db.Builds
.GroupBy(tb => tb.Code,
tb => tb,
gr => gr.OrderByDescending(gr => gr.BuildDate)
.First()
.BuildQuantity)
.Sum()
虽然我不会从可读性的角度推荐它