LINQ基于最新日期的条目总和

本文关键字:日期 于最新 最新 LINQ | 更新日期: 2023-09-27 18:24:08

我有一个这样的表:

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…我做错了什么?

LINQ基于最新日期的条目总和

在取第一个之前,您要对所有代码的BuildQuantity求和,而要对第一个求和。

int built = db.Builds
    .GroupBy(b => b.Code)
    .Sum(g => g.OrderByDescending(b => b.BuildDate).First().BuildQuantity); 

您正在查找每个代码的最后一个条目的构建数量的总和。您当前在分组之前进行订购,这实际上没有任何作用(在分组之后,订购没有定义)

因此,首先,您希望通过代码获得最新的元素。让我们先分组。我更愿意通过扩展方法写作:

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

Group by具有重载,允许您滚动组中的几乎所有内容。

如果你喜欢紧凑的代码,你可以写

var sum = db.Builds
          .GroupBy(tb => tb.Code,
                   tb => tb,
                   gr => gr.OrderByDescending(gr => gr.BuildDate)
                           .First()
                           .BuildQuantity)
          .Sum()

尽管从可读性的角度来看,我不建议使用