开发者

Help optimize this linq statement

开发者 https://www.devze.com 2023-04-05 01:39 出处:网络
Please help me optimize this linq statement for performance. There are about 4000 drivers to go through and the page times out.

Please help me optimize this linq statement for performance. There are about 4000 drivers to go through and the page times out. I am rather new to Linq

tblDriver driver = Mapper.Map<Domain.Driver, tblDriver>(driverDto);

var entries = (fr开发者_如何学Goom e in driver.tblDriverLogEntries
                where e.OccuredAt <= utcEnd &&
                e.OccuredAt >= utcViolationsStart &&
                e.tblDriverStatusChanges.Where(x => !x.RemovedAt.HasValue).Count() > 0
                select e).Union(
                    //previous amended status
                    (from e in driver.tblDriverLogEntries
                        where e.tblDriverStatusChanges.Where(s => !s.RemovedAt.HasValue).Count() > 0
                        && e.OccuredAt < utcViolationsStart
                        orderby e.OccuredAt descending
                        select e).Take(1).Union(
                            //next amended status
                            (from e in driver.tblDriverLogEntries
                                where e.tblDriverStatusChanges.Where(s => !s.RemovedAt.HasValue).Count() > 0
                                && e.OccuredAt > utcEnd
                                orderby e.OccuredAt ascending
                                select e)
                            )
                    );


where e.tblDriverStatusChanges.Where(x => !x.RemovedAt.HasValue).Count() > 0

You are using Count() > 0 when you should be using Any(): this will give you at least some speedup (occurs 3 times in your query):

 where e.tblDriverStatusChanges.Any(x => !x.RemovedAt.HasValue)

You also might want to pre-define and get the results for this query so you don't have to re-query 3 times, i.e:

var subset = (from e in driver.tblDriverLogEntries 
             where e.tblDriverStatusChanges.Any(x => !x.RemovedAt.HasValue)
             select e).ToList();

 var entries = (from e in subset 
                where e.OccuredAt <= utcEnd &&
                e.OccuredAt >= utcViolationsStart 
                select e).Union(
                //previous amended status
                (from e in subset
                 where e.OccuredAt < utcViolationsStart
                 orderby e.OccuredAt descending
                 select e).Take(1).Union(
                 //next amended status
                 (from e in subset
                  where e.OccuredAt > utcEnd
                  orderby e.OccuredAt ascending
                  select e)));
0

精彩评论

暂无评论...
验证码 换一张
取 消