Каково различие между несколькими где пункты и && оператор в LINQ-SQL?

Я действительно наткнулся на это, пытаясь выровнять столбцы. На всякий случай, если кто-то еще сделает то же самое, этот поток может быть полезен: Как вставить пробелы до столбца X, чтобы выстроить строки в столбцы?

8
задан Sedat Kapanoglu 4 November 2009 в 11:23
поделиться

4 ответа

Хорошо, вот мои выводы после некоторого просмотра выходных данных 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, когда это возможно.

8
ответ дан 5 December 2019 в 11:25
поделиться

Это дело LINQ to SQL, чтобы делать здесь правильные вещи. Я ожидал, что он преобразует два предложения «where» в одно предложение SQL, в котором две части будут соединены вместе с помощью «AND».

Попробуйте оба, но я очень сомневаюсь, что вы увидите какую-либо разницу в сгенерированном SQL.

ИМО, вы всегда должны смотреть на сгенерированный SQL на предмет чего-либо нетривиального, но способ работы LINQ определенно побуждает создавать большой запрос, составляя его из небольших предложений - поэтому я бы действительно ожидаю, что это просто сработает.

3
ответ дан 5 December 2019 в 11:25
поделиться

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).

2
ответ дан 5 December 2019 в 11:25
поделиться

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.

2
ответ дан 5 December 2019 в 11:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: