LINQ,仅在条件满足时才在每个组中首次记录

时间:2017-02-11 19:12:43

标签: c# linq

我有这个LINQ查询来选择每个组的第一条记录:

repo.GroupBy(x => x.Revision, (key, g) => g.OrderBy(y => y.CreationDate).First())

现在我只想在记录满足条件时选择每个组的第一条记录:

!x.Terminated

显然我无法在GroupBy中添加一个Where,因为它返回一个Object,我希望能够检查数据库中的条件,而不必将每个组的每个第一条记录都带到内存中并从那里开始运行。 / p>

** 修改

在我的设计中共享相同版本的一组记录意味着它是相同的寄存器,但编辑了很多次。这样,具有更新创建日期的记录是寄存器的实际修订版本或版本,并且组中的其余记录是历史记录。我的问题是我只是将组中的实际修订标记为已终止,因此在按创建日期对每个组进行分组并仅选择第一条记录之前,无法按终止的功能进行过滤。

现在作为我的问题的解决方案,我将在每次终止寄存器时将整个组标记为终止,以便稍后在分组之前过滤终止的记录,按日期排序并选择每个组的第一条记录为@Jon Skeet和@ThomasAndreèLin建议。

我会在没有接受答案的情况下暂时提出这个问题,也许有人可以提出一些其他内容,允许在分组,排序和选择每个组的第一条记录后按终止功能进行过滤。

2 个答案:

答案 0 :(得分:1)

返回IQueryable<T>的Linq方法被懒惰地评估并且未实现。

这意味着您实际上可以添加where条件,整个表达式树将相应地更新,然后转换为SQL(由DB提供程序)。

您错过了执行流程的一个重要方面:当您枚举集合时,将仅从db 中检索生成的db命令。

在Linq中Where之后链接Group不会导致内存过滤,而是在HAVING子句中,正是您所要求的。

流利版本可以简化为

repo.GroupBy(x => x.Revision)
.Select(x => x
   .OrderBy(y => y.CreationDate)
   .First())
.Where( x => !x.Terminated)

或者查询版本应为

var query = from rp in repo 
group rp by rp.Revision into grouped 
where !grouped.OrderBy(y => y.CreationDate).First().Terminated 
select grouped.OrderBy(y => y.CreationDate).First();

当然,如果能够通过类映射将上述查询转换为SQL,它依赖于数据库提供程序:它确实很难。

答案 1 :(得分:0)

我认为这可以解决问题。

repo.Where( x => !x.Terminated)
        .GroupBy(x => x.Revision, (key, g) => g.OrderBy(y => y.CreationDate).First())

据我所知,你想要消除所有Terminated元素(不妨在开头做)。

相关问题