我有这个LINQ查询来选择每个组的第一条记录:
repo.GroupBy(x => x.Revision, (key, g) => g.OrderBy(y => y.CreationDate).First())
现在我只想在记录满足条件时选择每个组的第一条记录:
!x.Terminated
显然我无法在GroupBy中添加一个Where,因为它返回一个Object,我希望能够检查数据库中的条件,而不必将每个组的每个第一条记录都带到内存中并从那里开始运行。 / p>
** 修改
在我的设计中共享相同版本的一组记录意味着它是相同的寄存器,但编辑了很多次。这样,具有更新创建日期的记录是寄存器的实际修订版本或版本,并且组中的其余记录是历史记录。我的问题是我只是将组中的实际修订标记为已终止,因此在按创建日期对每个组进行分组并仅选择第一条记录之前,无法按终止的功能进行过滤。
现在作为我的问题的解决方案,我将在每次终止寄存器时将整个组标记为终止,以便稍后在分组之前过滤终止的记录,按日期排序并选择每个组的第一条记录为@Jon Skeet和@ThomasAndreèLin建议。
我会在没有接受答案的情况下暂时提出这个问题,也许有人可以提出一些其他内容,允许在分组,排序和选择每个组的第一条记录后按终止功能进行过滤。
答案 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
元素(不妨在开头做)。