我搜索了档案但找不到解决方法。我试图通过 UniqueId 简单地对实体集合进行分组,然后按 RevisionNumber 排序,并返回每个UniqueId具有最高RevisionNumber的实体。
因此,对于样本数据,
[UniqueId, RevisionNumber]
[1, 1]
[1, 2]
[1, 3]
[1, 4]
[2, 1]
[2, 2]
[2, 3]
生成的集合将返回
[1, 4]
[2, 3]
有没有人看到如何将下面的两个语句组合成一个linq查询,该查询对集合进行排序,对其进行分组,并返回投影的DTO对象,仅针对每个唯一ID的最高版本?
谢谢!
private static IEnumerable<RevisionDto> ExtractHighestRevisions(IEnumerable<RevisionEntity> revisions)
{
var groupedRevisions = (from r in revisions
orderby r.RevisionNumber descending
group r by r.UniqueId
into grp
select grp.OrderByDescending(g => g.RevisionNumber).FirstOrDefault());
return (from r in groupedRevisions
orderby r.RevisionNumber
select new RevisionDto
{
// other properties omitted for clarity
UniqueId = r.UniqueId,
RevisionNumber = r.RevisionNumber
});
}
答案 0 :(得分:0)
我有点作弊,并使用morelinq中的MaxBy
运算符:
return revisions
.GroupBy(r => r.UniqueID)
.SelectMany(g => g.MaxBy(r => r.RevisionNumber))
.Select(r =>
new RevisionDto
{
UniqueId = r.UniqueId,
RevisionNumber = r.RevisionNumber
})
.OrderBy(r => r.RevisionNumber);
答案 1 :(得分:0)
我认为您可以使用以下方式执行此操作:
var q = from r in revisions
group r by r.UniqueId into grouped
select new ReveisonDto
{
UniqueId = grouped.Key,
RevisionNumber = grouped.Max(x => x.RevisionNumber)
};
但很明显,如果您真的想要获取原始对象而不是Dto
,这将无效答案 2 :(得分:0)
如果你问是否有办法将两个查询结合起来,那么这是一种天真的方式:
return from r in revisions
orderby r.RevisionNumber descending
group r by r.UniqueId
into grp
select grp.OrderByDescending(g => g.RevisionNumber).FirstOrDefault() into groupedRevisions
from r in groupedRevisions
orderby r.RevisionNumber
select new RevisionDto
{
// other properties omitted for clarity
UniqueId = r.UniqueId,
RevisionNumber = r.RevisionNumber
};
但是我会这样重写:
return from r in revisions
orderby r.RevisionNumber
group r by r.UniqueId
into grp
let r = grp.Last()
select new RevisionDto
{
// other properties omitted for clarity
UniqueId = r.UniqueId,
RevisionNumber = r.RevisionNumber
};
您必须以任何方式浏览整个集合,以便您可以排序一次并获取组中的最后一项。