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

rex*_*ghk 18 c# sql linq entity-framework

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

var students = SchoolContext.Students.Where(s => s.Name == "Foo" && s.Id == 1);
Run Code Online (Sandbox Code Playgroud)

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

SELECT *
FROM Students
WHERE Name = 'Foo' AND Id = 1
Run Code Online (Sandbox Code Playgroud)

但是如果我写的话,是否存在差异(关于性能):

var students = SchoolContext.Students
                            .Where(s => s.Name == "Foo")
                            .Where(s => s.Id == 1);
Run Code Online (Sandbox Code Playgroud)

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

Luk*_*ett 18

第一个.Where()条款仍将返回IQueryable<T>.只要您正在进行操作,IQueryable<T>它将继续构建SQL查询并在需要将集合带入内存时执行它(例如:在foreach循环或ToList()操作中使用@anaximander时说明.

因此:

SchoolContext.Students.Where(s => s.Name == "Foo").Where(s => s.Id == 1);
Run Code Online (Sandbox Code Playgroud)

仍然转化为:

SELECT *
FROM Students
WHERE Name = 'Foo' AND Id = 1
Run Code Online (Sandbox Code Playgroud)

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

SchoolContext.Students.Where(s => s.Name == "Foo").Where(s => s.Id == 1);
SchoolContext.Students.Where(s => s.Name == "Foo" && s.Id == 1);
Run Code Online (Sandbox Code Playgroud)

  • 在不使用分析器的情况下调试此方法的一种好方法是断开代码并将鼠标悬停在Visual Studio中的变量上,就像通常用来查看某些内容的值一样.它会在展开时显示生成的SQL. (4认同)
  • @SLC:请注意,您所说的只有在使用现代Entity Framework的`DbContext` API和相关的`DbQuery`时才有效.如果他使用`ObjectContext`和相关的`ObjectQuery`,则需要调用`ToTraceString`.(原因:`DbQuery`的`ToString`实现调用`ObjectQuery.ToTraceString`). (3认同)

emp*_*mpi 7

首先返回,IQueryable<T>所以不会有性能差异.