0

select を使用してデータベースから生データをオブジェクトに変換し、その過程でいくつかの計算を実行する LINQ to Entity クエリがあります。計算は数回繰り返されるので、let を利用するように LINQ をリファクタリングしてみました。ただし、そうすると、パフォーマンスが大幅に低下します。パフォーマンスに影響を与えずにコードを再利用するためだけに使用できる LET の代替手段はありますか?

var defaultHours = 40;
var defaultOldPersonPoints = 100;
var defaultYoungPersonPoints = 50;

// Example with no let but lots of ugly, unreadable, redundant code
var exampleNoLet =
    (from p in people
     join op in otherPeople
         on p.PersonId equals op.PersonId into inner
     from outer in inner.DefaultIfEmpty(null)
     select new
     {
         AllocatedPoints = (p.PersonTypeId == (int)PersonType.Old
                            ? defaultOldPersonPoints
                            : p.PersonTypeId == (int)PersonType.Young
                            ? defaultYoungPersonPoints : 0)
                            + (int)(
                            (p.PersonTypeId == (int)PersonType.Old
                            ? defaultOldPersonPoints
                            : p.PersonTypeId == (int)PersonType.Young
                            ? defaultYoungPersonPoints : 0)
                            * (p.ContractedHours.HasValue
                            ? (p.ContractedHours.Value - defaultHours) / defaultHours : 0))
     });


// Using the LET allows me to clean up the code somewhat but causes a massive performance hit
var exampleUsingLet =
    (from p in people
     join op in otherPeople
         on p.PersonId equals op.PersonId into inner
     from outer in inner.DefaultIfEmpty(null)
     let defaultPoints = p.PersonTypeId == (int)PersonType.Old
                            ? defaultOldPersonPoints
                            : p.PersonTypeId == (int)PersonType.Young
                            ? defaultYoungPersonPoints : 0
     let contractedHourRatio = p.ContractedHours.HasValue 
                            ? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
     select new
     {
         AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
     });
4

1 に答える 1