Cuide do desempenho:
Eu experimentei que pelo menos com o EF Core as diferentes respostas fornecidas aqui podem resultar em desempenho diferente. Estou ciente de que o OP perguntou sobre o Linq to SQL, mas parece-me que as mesmas perguntas ocorrem também com o EF Core.
Em um caso específico que eu tive que lidar, a sugestão (sintaticamente mais agradável) de Marc Gravell resultou em junções esquerdas dentro de uma aplicação cruzada - semelhante ao que Mike U descreveu - que resultou em que os custos estimados para essa consulta específica eram dois vezes mais alto em comparação com uma consulta sem junções cruzadas . Os tempos de execução do servidor diferiram por um fator de 3 . [1]
A solução de Marc Gravell resultou em uma consulta sem junções cruzadas.
Contexto: eu basicamente precisava realizar duas junções esquerdas em duas tabelas, cada uma das quais novamente exigia uma junção a outra tabela. Além disso, lá eu tive que especificar outras condições onde nas tabelas nas quais eu precisava aplicar a junção esquerda. Além disso, eu tinha duas junções internas na mesa principal.
Custos estimados do operador:
- com cruz aplicar: 0,2534
- sem aplicação cruzada: 0,0991.
Tempos de execução do servidor em ms (consultas executadas 10 vezes; medidas usando SET STATISTICS TIME ON):
- com cruz aplicar: 5, 6, 6, 6, 6, 6, 6, 6, 6, 6
- sem aplicação cruzada: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
(A primeira execução foi mais lenta nas duas consultas; parece que algo está armazenado em cache.)
Tamanhos da tabela:
- tabela principal: 87 linhas,
- primeira tabela para junção esquerda: 179 linhas;
- segunda tabela para junção esquerda: 7 linhas.
Versão EF Core: 2.2.1.
Versão do SQL Server: MS SQL Server 2017 - 14 ... (no Windows 10).
Todas as tabelas relevantes tinham índices apenas nas chaves primárias.
Minha conclusão: é sempre recomendável olhar para o SQL gerado, pois ele pode realmente diferir.
[1] Curiosamente, ao definir as 'Estatísticas do cliente' no MS SQL Server Management Studio, pude ver uma tendência oposta; ou seja, a última execução da solução sem aplicação cruzada levou mais de 1s. Suponho que algo estava errado aqui - talvez com a minha configuração.