Подтвердить что ты не робот

Производительность для использования предложений where 2 в LINQ

В 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() будет фильтровать сущности in-memory вместо перевода IQueryable<T> в SQL, это правильно?

4b9b3361

Ответ 1

Первое предложение .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);

Ответ 2

First Где возвращает IQueryable<T>, поэтому разница в производительности не будет.

Ответ 3

Нет, это будет тот же запрос.

Вы можете составить более сложный запрос плавно, связав IQueryable, возвращаемый каждой операцией Linq. Оператор не генерируется и не отправляется на сервер до тех пор, пока вы не оцените результаты.

Вы можете проверить фактический запрос, сгенерированный путем отладки и зависания запроса или сделать ToTraceString(), или с помощью инструмента, такого как SQLProfiler, для мониторинга сервера базы данных.

Ответ 4

Оба должны создать один и тот же SQL; IQueryable умный, поскольку он фактически не оценивает, пока это не понадобится. Второй .Where() должен добавить к первому, а затем всякий раз, когда вы используете .ToList(), .Count(), foreach или что-либо, что должно знать, что в IQueryable, оно будет генерировать SQL, запросить базу данных и дать вам результат.

Ответ 5

Получить Linqpad и попробовать различные запросы. Вы можете напрямую добавить соединение к своим объектам, запустить запросы и посмотреть, какой SQL создается в каждом случае. Отличный способ экспериментировать с Linq.