在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,这是正确的吗?
答案 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的绝佳方式。