19

在 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,对吗?

4

5 回答 5

19

第一个.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);
于 2013-10-15T09:21:43.737 回答
7

首先 Where 返回IQueryable<T>,因此不会有性能差异。

于 2013-10-15T09:19:13.823 回答
2

不,这将是相同的查询。

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

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

于 2013-10-15T09:20:25.940 回答
1

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

于 2013-10-15T09:20:33.807 回答
1

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

于 2013-10-15T09:24:03.383 回答