帮助优化这个linq语句

本文关键字:linq 语句 优化 帮助 | 更新日期: 2023-09-27 18:08:39

请帮我优化这个linq语句的性能。大约有4000个驱动程序要通过,页面超时。我对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)
                            )
                    );

帮助优化这个linq语句

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

当你应该使用Any()时,你正在使用Count() > 0:这将给你至少一些加速(在你的查询中发生3次):

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

你也可能想要预先定义并得到这个查询的结果,这样你就不必重新查询3次,即:

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