3

人がプロジェクトを開始したときの追跡のようなテーブルがあります。

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()
})

これを行うためのよりパフォーマンスの高い方法はありますか?

4

1 に答える 1

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テーブル自体を読み取るのと同じくらい優れています。

于 2013-10-04T15:33:20.553 に答える