LINQ Query生成不必要的长SQL

时间:2017-01-18 13:22:35

标签: c# .net linq

我有很多服务,他们引用学生(多对一),他们引用了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来生成这样的查询。任何专家都可以告诉我为什么会这样吗?或者我如何以另一种方式编写我的查询。

2 个答案:

答案 0 :(得分:1)

实体框架几乎没有尝试优化生成的SQL - 实际上恰恰相反。它意味着方便而不是快速。

LINQ和实体框架是免费的,但Windows Azure会在第二次收费以进行数据库访问。查询越慢,微软赚的钱就越多。 所以我相信微软真的非常努力地为你加速。

如果您需要速度但无法从EF获得,可以选择:

  • 编写SQL存储过程或SQL视图 - 两者都可以从实体框架中调用。
  • 在SQL中编写自己的查询并使用ADO.NET
  • 执行它
  • 使用LINQ查询,直到它自己加速

答案 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只是出于某些原因,在这种情况下,这两个重复的块真正杀死了性能。