Prenditi cura delle prestazioni:
Ho riscontrato che almeno con EF Core le diverse risposte fornite qui potrebbero comportare prestazioni diverse. Sono consapevole che l'OP ha chiesto di Linq a SQL, ma mi sembra che le stesse domande si verifichino anche con EF Core.
In un caso specifico che ho dovuto affrontare, il suggerimento (sintatticamente più gradevole) di Marc Gravell ha comportato l'applicazione di join a sinistra all'interno di una croce - analogamente a quanto descritto da Mike U - che ha prodotto il risultato che i costi stimati per questa specifica query erano due volte più elevato rispetto a una query senza join incrociati . I tempi di esecuzione del server differivano di un fattore 3 . [1]
La soluzione di Marc Gravell ha portato a una query senza cross-join.
Contesto: avevo essenzialmente bisogno di eseguire due join a sinistra su due tabelle, ognuno dei quali richiedeva nuovamente un join a un'altra tabella. Inoltre, lì ho dovuto specificare altre condizioni dove sui tavoli su cui avevo bisogno di applicare il join sinistro. Inoltre, avevo due join interni sul tavolo principale.
Costi stimati dell'operatore:
- con croce applicare: 0,2534
- senza croce applicare: 0.0991.
Tempi di esecuzione del server in ms (query eseguite 10 volte; misurate utilizzando SET STATISTICS TIME ON):
- con croce applicare: 5, 6, 6, 6, 6, 6, 6, 6, 6, 6
- senza croce applicare: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
(La prima esecuzione è stata più lenta per entrambe le query; sembra che qualcosa sia memorizzato nella cache.)
Tabella dimensioni:
- tabella principale: 87 file,
- prima tabella per join sinistro: 179 righe;
- seconda tabella per join sinistro: 7 righe.
Versione EF Core: 2.2.1.
Versione di SQL Server: MS SQL Server 2017 - 14 ... (su Windows 10).
Tutte le tabelle pertinenti avevano indici solo sulle chiavi primarie.
La mia conclusione: si consiglia sempre di guardare l'SQL generato poiché può davvero differire.
[1] È interessante notare che, impostando le "Statistiche client" in MS SQL Server Management Studio, ho potuto vedere una tendenza opposta; vale a dire che l'ultima esecuzione della soluzione senza applicazione incrociata ha richiesto più di 1 secondo. Suppongo che qui qualcosa non andasse, forse con la mia configurazione.