简体   繁体   中英

Help optimize this linq statement

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 = (from 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, ie:

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)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM