Я действительно наткнулся на это, пытаясь выровнять столбцы. На всякий случай, если кто-то еще сделает то же самое, этот поток может быть полезен: Как вставить пробелы до столбца X, чтобы выстроить строки в столбцы?
Хорошо, вот мои выводы после некоторого просмотра выходных данных Reflector. LINQ-to-Objects объединяет последовательные предикаты where
при использовании WhereArrayIterator
или WhereListIterator
, заставляя его ПОЧТИ как оператор &&, но не так точно:
Когда вы используете xa == 1 && xb == 1
, предложение where преобразуется в Func
, которое выглядит следующим образом:
bool daspredicate(TSource x)
{
return x.a==1 && x.b==1
}
Однако, когда вы используете последовательный Where есть небольшое снижение производительности, по крайней мере, из-за не JITted IL-аспекта. Вот как выглядит код после объединения:
bool predicate1(TSource x)
{
return x.a==1;
}
bool predicate2(TSource x)
{
return x.b==1;
}
bool daspredicate(TSource x)
{
return predicate1(x) && predicate2(x);
}
Как видите, это связано с дополнительными накладными расходами на вызов функций. Это может быть довольно дорого, если JIT не встраивает функции. Я уверен, что он хорошо справляется с этим, но теперь мы знаем JIT ' Работа становится намного проще, если мы сами комбинируем наши операторы Where, если в этом нет необходимости.
Что касается SQL, то запросы такие же. Еще до выполнения отладчик оценивает объект запроса в том же операторе SQL. Я не мог зайти слишком далеко в пространстве имен Linq, потому что все казалось намного более сложным, но поскольку запросы одинаковы, не должно быть никаких штрафов, в отличие от приведенного выше примера LINQ-to-objects.
РЕДАКТИРОВАТЬ: Я видел случаи, когда несколько где операторы, приводящие к вложенным подзапросам на сервере SQL. Я думаю, чтобы быть в безопасности, лучше придерживаться одинарных утверждений where, когда это возможно.
отладчик оценивает объект запроса в том же операторе SQL. Я не мог зайти слишком далеко в пространстве имен Linq, потому что все казалось намного более сложным, но поскольку запросы одинаковы, не должно быть никаких штрафов, в отличие от приведенного выше примера LINQ-to-objects.РЕДАКТИРОВАТЬ: Я видел случаи, когда несколько где операторы, приводящие к вложенным подзапросам на сервере SQL. Я думаю, чтобы быть в безопасности, лучше придерживаться одинарных утверждений where, когда это возможно.
отладчик оценивает объект запроса в том же операторе SQL. Я не мог зайти слишком далеко в пространстве имен Linq, потому что все казалось намного более сложным, но поскольку запросы одинаковы, не должно быть никаких штрафов, в отличие от приведенного выше примера LINQ-to-objects.EDIT: Я видел случаи, когда несколько где операторы, приводящие к вложенным подзапросам на сервере SQL. Я думаю, чтобы быть в безопасности, лучше придерживаться одинарных утверждений where, когда это возможно.
Это дело LINQ to SQL, чтобы делать здесь правильные вещи. Я ожидал, что он преобразует два предложения «where» в одно предложение SQL, в котором две части будут соединены вместе с помощью «AND».
Попробуйте оба, но я очень сомневаюсь, что вы увидите какую-либо разницу в сгенерированном SQL.
ИМО, вы всегда должны смотреть на сгенерированный SQL на предмет чего-либо нетривиального, но способ работы LINQ определенно побуждает создавать большой запрос, составляя его из небольших предложений - поэтому я бы действительно ожидаю, что это просто сработает.
DB side they are identical. It is just a side effect of Linq-to-SQL being composable (i.e. you can start off with one query and then add additional criteria to it, change projections etc).
The code:
where x.a==1
where x.b==1
or
where x.a==1 && x.b==1
is syntactic sugar for C# anyway. It will compile as a LINQ method chain of
Where(...).Where(...)
just as you guessed it probably would, so I really doubt there is any difference in the generated SQL. Try using a tool like Resharper from Jetbrains - it even offers intellisense that gives you the choice to auto-convert between the two to save you time re-writing it for testing.
My preference is to write really simple queries as method chains, (e.g. where there is only 1 collection/table involved and no joins) and anything more complicated in the more expressive Linq sugar-syntax.