我正在构建一个搜索功能,需要返回按相关性排序的列表。
IList<ProjectDTO> projects = new List<ProjectDTO>();
projects = GetSomeProjects();
List<ProjectDTO> rawSearchResults = new List<ProjectDTO>();
//<snip> - do the various search functions here and write to the rawSearchResults
//now take the raw list of projects and group them into project number and
//number of search returns.
//we will sort by number of search returns and then last updated date
var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)
.Select(x => new
{
Count = x.Count(),
ProjectNbr = x.Key,
LastUpdated = x.First().UpdatedDateTime
})
.OrderByDescending(x => x.Count)
.ThenByDescending(x => x.LastUpdated);
到目前为止一切顺利; “orderedProjects”变量以正确的顺序返回我的列表。但是,我需要整个对象用于下一步。当我尝试查询以获取原始对象类型时,我的结果会丢失其顺序。回想起来,这是有道理的,但我需要找到解决方法。
projects = (from p in projects
where orderedProjects.Any(o => o.ProjectNbr == p.ProjectNbr)
select p).ToList();
是否有一个LINQ友好的方法来保存上述项目查询中的顺序?
我可以遍历orderedProject列表并获取每个项目,但这不是很有效。我也可以在原始的orderedProjects查询中重建整个对象,但是如果可能的话我想避免这种情况。
答案 0 :(得分:3)
你需要反过来做这件事:
查询orderedProjects
并从projects
中选择相应的项目:
var projects =
orderedProjects
.Select(o => projects.SingleOrDefault(p => p.ProjectNbr == o.ProjectNbr))
.Where(x => x != null) // This is only necessary if there can be
// ProjectNbrs in orderedProjects that are not in
// projects
.ToList();
答案 1 :(得分:1)
您不应该在中间使用“选择”,因为该操作符将对象转换为另一种类型,并且您说您需要原始对象。
var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)
.OrderByDescending(x => x.Count)
.ThenByDescending(x => x.First().UpdatedDateTime);
他们按时间顺序排列还是什么?否则,我很确定您希望在最新或最旧的项目更新中执行“ThenByDescending”,如下所示:
var orderedProjects = rawSearchResults.GroupBy(x => x.ProjectNbr)
.OrderByDescending(x => x.Count)
.ThenByDescending(x => x.Max(p=>p.UpdatedDateTime));