我有以下一些代码,而使用toList的最后一个语句需要很长时间。我有什么想法可以改善这个吗?
//This statement takes less than 1 second
var inspectorData = context.COESDetails.Where(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth.Contains(criteria.AuditYear)).Select(x => x.Inspector).Where(y => y.Id != 0).Distinct().OrderBy(x => x.Firstname).ToList();
//This statement takes less than 1 second
var coesData = context.COESDetails.Where(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth.Contains(criteria.AuditYear)).ToList();
//this takes less than 1 second
var nonComplianceData = inspectorData
.Select(ud =>
new NonComplianceData
{
InspectorId = ud.Id,
InspectorName = ud.Firstname + " " + ud.Surname,
FullYearData = Constants.Months.Select(month => new MonthData
{
Month = month,
TotalAuditsCompleted = coesData.Count(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth == (month + " " + criteria.AuditYear) && x.InspectorId == ud.Id && x.AuditType != (int)AuditType.NotSelected),
TotalNoDefects = coesData.Count(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth == (month + " " + criteria.AuditYear) && x.InspectorId == ud.Id && x.AuditType != (int)AuditType.NotSelected && x.COESDetailsCOESDefects.Any())
}).ToList()
});
// this statement takes about 14 seconds
return nonComplianceData.ToList();
我想当我在前两个语句中调用toList()时,我认为查询正在执行,并且我有所需的数据。那么为什么最后的Tolist()花了这么长时间呢?考虑到所有必需的数据已经存在..
任何见解?想法?
答案 0 :(得分:1)
当调用最后一个ToList()
时,它将为nonCompianceData
中的所有项目执行此代码,这可能需要很长时间。
FullYearData = Constants.Months.Select(month => new MonthData
{
Month = month,
TotalAuditsCompleted = coesData.Count(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth == (month + " " + criteria.AuditYear) && x.InspectorId == ud.Id && x.AuditType != (int)AuditType.NotSelected),
TotalNoDefects = coesData.Count(x => x.UploadCOESDetails.AuditZoneId == criteria.AuditZoneId && x.UploadCOESDetails.AuditMonth == (month + " " + criteria.AuditYear) && x.InspectorId == ud.Id && x.AuditType != (int)AuditType.NotSelected && x.COESDetailsCOESDefects.Any())
}).ToList()
我理解你在使用Linq返回的ToList()
查询之前不应该使用IEnumerable<T>
。
除了它是关于优化你的Linq以生成更快的SQL。
答案 1 :(得分:0)
假设您正在使用Entity Framework(或其他ORM)...
那些coesData.Count(...
导致加载UploadCOESDetails
和COESDetailsCOESDefects
懒惰。
使用
context.COESDetails
.Include(x => x.UploadCOESDetails)
.Include(x => x.COESDetailsCOESDefects)
急切地加载它们。
或者在查询中挑选您需要的东西
var coesData = context.CoesData.Select(x => new
{
x.Id,
x.UploadCOESDetails.AuditZoneId,
x.UploadCOESDetails.AuditMonth,
x.InspectorId,
x.AuditType,
/* etc. */
DefectCount = x.COESDetailsCOESDefects.Count(),
/* or this if it works... */
HasDefects = x.COESDetailsCOESDefects.Any()
})