我的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属性而没有问题。无论如何,我不确定我的怀疑是否正确,如果是的话,为什么会发生以及如何解决它。
答案 0 :(得分:0)
我怀疑要获取 CompanyId , CompanyName 和 Date 的表达式太复杂,Linq To Sql无法在正确的Sql中翻译它
1)尝试删除选择 CompanyId , CompanyName 和 Date 的部分以查看它是否变快;
var result =
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 { CompanyId = user.CompanyId, CompanyName = company.Name, Date = data.Date } into g
select new GroupedDayData
{
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),
};
2)如果有帮助,请用g.Key.CompanyId
,g.Key.CompanyName
和g.Key.Date
var result =
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 { CompanyId = user.CompanyId, CompanyName = company.Name, Date = data.Date } into g
select new GroupedDayData
{
Id = g.Key.CompanyId,
Name = g.Key.CompanyName,
Date = g.Key.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),
};
3)如果这有帮助,请添加null check,你应该得到相同的结果,但速度更快;
var result =
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 { CompanyId = user.CompanyId, CompanyName = company.Name, Date = data.Date } into g
select new GroupedDayData
{
Id = g.Key.CompanyId ?? "None",
Name = g.Key.CompanyName ?? "None",
Date = g.Key.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),
};