Escrevo uma quantidade razoável de linq no meu dia-a-dia, mas principalmente declarações simples. Percebi que, ao usar as cláusulas where, há muitas maneiras de escrevê-las e cada uma tem os mesmos resultados, tanto quanto eu sei. Por exemplo;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
Parece ser equivalente a isso, pelo menos no que diz respeito aos resultados:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
Então, existe realmente outra diferença além da sintaxe? Se sim, qual é o estilo preferido e por quê?
Fat
propriedade booleana ? Isso é maldade.Respostas:
O segundo seria mais eficiente, pois apenas possui um predicado para avaliar em relação a cada item da coleção. Como no primeiro, ele aplica o primeiro predicado a todos os itens primeiro e o resultado (que é reduzido nesse momento) é usado para o segundo predicado e assim por diante. Os resultados são reduzidos a cada passo, mas ainda envolvem vários passes.
Além disso, o encadeamento (primeiro método) funcionará apenas se você estiver ANDing com seus predicados. Algo assim
x.Age == 10 || x.Fat == true
não funcionará com o seu primeiro método.fonte
EDIT: LINQ to Objects não se comporta como eu esperava. Você pode estar interessado no post que acabei de escrever sobre isso ...
Eles são diferentes em termos do que será chamado - o primeiro é equivalente a:
sendo que o último é equivalente a:
Agora, a diferença que realmente faz depende da implementação de
Where
ser chamado. Se for um provedor baseado em SQL, espero que os dois acabem criando o mesmo SQL. Se estiver no LINQ to Objects, o segundo terá menos níveis de indireção (haverá apenas dois iteradores envolvidos em vez de quatro). Se esses níveis de indireção são significativos em termos de velocidade é uma questão diferente.Normalmente, eu usaria várias
where
cláusulas se elas sentissem que estão representando condições significativamente diferentes (por exemplo, uma diz respeito a uma parte de um objeto e outra é completamente separada) e umawhere
cláusula quando várias condições estão intimamente relacionadas (por exemplo, um valor específico é maior que um mínimo e menor que um máximo). Basicamente, vale a pena considerar a legibilidade antes de qualquer pequena diferença de desempenho.fonte
O primeiro será implementado:
Ao contrário do muito mais simples (e
muito mais rápido,presumivelmente mais rápido):fonte
quando eu corro
e
na minha tabela Customer, ele produz a mesma consulta sql
portanto, na tradução para o sql não há diferença e você já viu em outras respostas como elas serão convertidas em expressões lambda
fonte
Olhando sob o capô, as duas instruções serão transformadas em diferentes representações de consulta. Dependendo
QueryProvider
doCollection
, isso pode ser otimizado ou não.Quando se trata de uma chamada linq para objeto, várias cláusulas where levarão a uma cadeia de IEnumerables que são lidas uma da outra. Usar o formulário de cláusula única ajudará o desempenho aqui.
Quando o provedor subjacente o converte em uma instrução SQL, são grandes as chances de as duas variantes criarem a mesma instrução.
fonte