В повседневной жизни я пишу изрядное количество linq, но в основном это простые операторы. Я заметил, что при использовании предложений where существует множество способов их записи, и каждый из них дает одинаковые результаты, насколько я могу судить. Например;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
Похоже, что это эквивалентно, по крайней мере, в том, что касается результатов:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
Так есть ли разница, кроме синтаксиса? Если да, то какой стиль предпочтительнее и почему?
Fat
свойство? Это просто подло.Ответы:
Второй был бы более эффективным, поскольку у него есть только один предикат для оценки каждого элемента в коллекции, где, как и в первом, он сначала применяет первый предикат ко всем элементам, а результат (который на данном этапе сужен) используется для второго предиката и так далее. Результаты сужаются с каждым проходом, но все же требуется несколько проходов.
Также цепочка (первый метод) будет работать только в том случае, если вы выполняете операцию AND для своих предикатов. Что-то подобное
x.Age == 10 || x.Fat == true
не сработает с вашим первым методом.источник
РЕДАКТИРОВАТЬ: LINQ to Objects ведет себя не так, как я ожидал. Возможно, вас заинтересует сообщение в блоге, которое я только что написал об этом ...
Они разные с точки зрения того, что будут называться - первый эквивалент:
где последнее эквивалентно:
Теперь, какая разница на самом деле зависит от реализации
Where
вызова. Если это провайдер на основе SQL, я ожидаю, что они оба создадут один и тот же SQL. Если он находится в LINQ to Objects, второй будет иметь меньше уровней косвенности (будет задействовано только два итератора вместо четырех). Другой вопрос, являются ли эти уровни косвенного обращения значительными с точки зрения скорости.Обычно я бы использовал несколько
where
предложений, если они чувствовали, что они представляют существенно разные условия (например, одно относится к одной части объекта, а другое полностью отделено) и одноwhere
предложение, когда различные условия тесно связаны (например, конкретное значение больше минимума и меньше максимума). В принципе, стоит подумать о удобочитаемости перед любой небольшой разницей в производительности.источник
Будет реализовано первое:
В отличие от гораздо более простого (и, предположительно,
гораздобыстрее):источник
когда я бегу
и
против моей таблицы клиентов он выводит тот же запрос sql
поэтому в переводе на sql нет разницы, и вы уже видели в других ответах, как они будут преобразованы в лямбда-выражения
источник
Заглянув под капот, два оператора будут преобразованы в разные представления запросов. В зависимости от
QueryProvider
тогоCollection
, это может быть оптимизировано или нет.Когда это вызов linq-to-object, несколько предложений where приведут к цепочке IEnumerables, которые читают друг от друга. Использование формы с одним предложением поможет повысить производительность здесь.
Когда базовый поставщик преобразует его в оператор SQL, велика вероятность того, что оба варианта создадут один и тот же оператор.
источник