【发布时间】:2015-08-06 00:22:32
【问题描述】:
我有一个 Linq 查询花费的时间比它的等效 SQL 长得多(Linq 大约 5-6 秒,SQL 大约 50 毫秒)。显然翻译出了点问题,我什至知道是什么,但我不知道如何解决。查询如下:
from data in DbContext.CoacheeData
group data by new { data.User.CompanyId, data.Date } into g
select new GroupedDayData
{
Id = g.FirstOrDefault().User.CompanyId == null ? "none" : g.FirstOrDefault().User.CompanyId,
Name = g.FirstOrDefault().User.Company.Name == null ? "none" : g.FirstOrDefault().User.Company.Name,
Date = g.FirstOrDefault().Date,
Steps = g.Sum(x => x.Steps),
Distance = g.Sum(x => x.Distance),
CaloriesBurned = g.Sum(x => x.CaloriesBurned),
LightlyActiveMinutes = g.Sum(x => x.LightlyActiveMinutes),
FairlyActiveMinutes = g.Sum(x => x.FairlyActiveMinutes),
VeryActiveMinutes = g.Sum(x => x.VeryActiveMinutes),
};
我怀疑在我的 group by 中使用导航属性 User 会导致为 CoacheeData 中的每条记录执行子查询。通过手动加入用户和公司表,我可以将效率提高大约 1.5 秒,如下所示:
from data in DbContext.CoacheeData
join user in DbContext.Users on data.UserId equals user.Id
join company in DbContext.Companies on user.CompanyId equals company.Id
group data by new { user.CompanyId, company.Name, data.Date } into g
select new GroupedDayData
{
Id = g.FirstOrDefault().User.CompanyId == null ? "none" : g.FirstOrDefault().User.CompanyId,
Name = g.FirstOrDefault().User.Company.Name == null ? "none" : g.FirstOrDefault().User.Company.Name,
Date = g.FirstOrDefault().Date,
Steps = g.Sum(x => x.Steps),
Distance = g.Sum(x => x.Distance),
CaloriesBurned = g.Sum(x => x.CaloriesBurned),
LightlyActiveMinutes = g.Sum(x => x.LightlyActiveMinutes),
FairlyActiveMinutes = g.Sum(x => x.FairlyActiveMinutes),
VeryActiveMinutes = g.Sum(x => x.VeryActiveMinutes),
};
但我的选择看起来仍然相同,也许那里的导航属性导致了类似的问题?不过这看起来很奇怪,因为我之前在选择 Linq 查询时使用了 navigatio 属性而没有问题。无论如何,我不确定我的怀疑是否正确,如果正确,为什么会发生以及如何解决。
【问题讨论】:
-
不需要
g.FirstOrDefault(),因为只有在groupby返回集合时才会运行选择。
标签: c# performance linq