我有很多服务,他们引用学生(多对一),他们引用了StudentEnrollments(一对多)。
当我查询这些服务时,它生成的SQL包含2个看起来相同的块,这会降低性能。我不能为我的生活找出原因。
这是我的C#代码(缩小版):
resolve: { extensions: ['*', '.js', '.jsx']},
这是生成的SQL:
IQueryable<StudentServiceDm> query = GetListQuery();
List<int> schoolIds = // from front-end: in this case: 20, 21, 22, 23, 89, 90, 93, 95
query = query.Where(m => m.Student.StudentEnrollments.Any(s => schoolIds.Contains(s.SchoolId.Value)));
IQueryable<StudentServiceDto> dtoQuery = query.Select(m => new StudentServiceDto
{
Id = m.Id,
Name = m.Name,
ParentParticipationCount = m.ParentCount,
StudentFirstName = m.Student.FirstName,
StudentLastName = m.Student.LastName,
StudentId = m.StudentId.Value,
StudentServiceType = m.StudentServiceType.Name,
StudentServiceSubType = m.StudentServiceSubType.Name,
Date = m.Date,
DurationInMinutes = m.DurationInMinutes
});
return dtoQuery;
如您所见,SQL正在执行两个布尔块(A和B),其中A和B看起来完全相同(当然[extend]后缀不同)。我认为我的查询很简单,不会混淆LINQ来生成这样的查询。任何专家都可以告诉我为什么会这样吗?或者我如何以另一种方式编写我的查询。
答案 0 :(得分:1)
实体框架几乎没有尝试优化生成的SQL - 实际上恰恰相反。它意味着方便而不是快速。
LINQ和实体框架是免费的,但Windows Azure会在第二次收费以进行数据库访问。查询越慢,微软赚的钱就越多。 所以我相信微软真的非常努力地为你加速。
如果您需要速度但无法从EF获得,可以选择:
答案 1 :(得分:0)
query = query.Where(m => m.Student.StudentEnrollments.Any(s => schoolIds.Contains(s.SchoolId.Value)));
到
query = query.Where(a => schoolIds.Any(b => a.Student.StudentEnrollments.Select(c => c.SchoolId.Value).Contains(b)));
我翻转逻辑并生成一个提高性能的查询。即使它更长并且不理想,但至少它是正确的#34;。第一个LINQ只是出于某些原因,在这种情况下,这两个重复的块真正杀死了性能。