当一个人开始一个项目时,我有一个看起来像跟踪的表:
PersonId
ProjectId
StartDate
我想使用linq(linq-to-entities)来获取像这样的结果集
PersonId
ProjectId
StartDate
EndDate
其中EndDate是下一个项目的StartDate(按StartDate排序),如果没有最近的项目,则为null。
这就是我所做的:
context.PersonProjects.Select(pp => new {
pp.PersonId,
pp.ProjectId,
pp.StartDate,
EndDate = context.PersonProjects.Where(pp2 => pp2.PersonId == pp.PersonId && pp2.StartDate > pp.StartDate).OrderBy(pp2 => pp2.StartDate).Select(pp2 => pp2.StartDate).FirstOrDefault()
})
有更高效的方法吗?
答案 0 :(得分:1)
更高效(但不那么干净)的方式是将所有内容读入开始日期排序的列表,然后遍历列表,并抓住以下项目的开始日期,如果有的话:
// You need a named class in order to make this work
class PersonProject {
int PersonId {get;set;}
int ProjectId {get;set;}
DateTime StartDate {get;set;}
DateTime EndDate {get;set;}
}
...
// Run your query, and put the results in a list
var listOfProjects = context
.PersonProjects
.OrderBy(pp => pp.StartDate)
.Select(pp => new PersonProject {
PersonId = pp.PersonId,
ProjectId = pp.ProjectId,
StartDate = pp.StartDate
}).ToList();
// Now walk through the list, setting the end time to the start of the next item
for (int i = 0 ; i < listOfProjects.Length-1 ; i++) {
listOfProjects[i].EndDate = listOfProjects[i+1].StartDate;
}
此解决方案的查询和“修正”部分都是线性的,因此性能与读取PersonProject
表本身一样好。