在LINQ中使用2 where子句的性能

时间:2013-10-15 09:16:57

标签: c# sql linq entity-framework

在LINQ-to-Entities中,您可以通过执行以下操作来查询实体:

var students = SchoolContext.Students.Where(s => s.Name == "Foo" && s.Id == 1);

我知道在幕后它将被翻译成类似于以下内容的SQL:

SELECT *
FROM Students
WHERE Name = 'Foo' AND Id = 1

但是,如果我写的话,是否存在差异(就性能而言):

var students = SchoolContext.Students
                            .Where(s => s.Name == "Foo")
                            .Where(s => s.Id == 1);

它会被翻译成相同的SQL查询吗?根据我的理解,.Where()将返回IEnumerable<T>,因此第二个.Where()将过滤内存中的实体而不是将IQueryable<T>转换为SQL,这是正确的吗?

5 个答案:

答案 0 :(得分:18)

第一个.Where()子句仍将返回IQueryable<T>。只要您在IQueryable<T>上运行,它就会继续构建SQL查询并在需要将集合带入内存时执行它(例如:@anaximander在foreach循环中使用时表示或ToList()操作。

因此:

SchoolContext.Students.Where(s => s.Name == "Foo").Where(s => s.Id == 1);

仍然转化为:

SELECT *
FROM Students
WHERE Name = 'Foo' AND Id = 1

虽然以下2个语句将转换为相同的查询:

SchoolContext.Students.Where(s => s.Name == "Foo").Where(s => s.Id == 1);
SchoolContext.Students.Where(s => s.Name == "Foo" && s.Id == 1);

答案 1 :(得分:7)

首先返回IQueryable<T>,这样就没有性能差异。

答案 2 :(得分:2)

不,它将是相同的查询。

您可以通过fluently链接每个Linq操作返回的IQueryable撰写越来越复杂的查询。在您评估结果之前,不会生成语句并将其发送到服务器。

您可以检查通过调试和将鼠标悬停在查询or doing a ToTraceString()上生成的实际查询,或者使用SQLProfiler之类的工具来监视数据库服务器。

答案 3 :(得分:1)

这两个应该生成相同的SQL; IQueryable很聪明,因为它不需要实际评估。第二个.Where()应添加到第一个,然后每当您使用.ToList().Count()foreach或任何需要知道 的内容时IQueryable,它将生成SQL,查询数据库并为您提供结果。

答案 4 :(得分:1)

获取Linqpad,然后尝试不同的查询。您可以直接向实体添加连接,运行查询,并查看在每种情况下生成的SQL。实验Linq的绝佳方式。