2009-11-04 17 views
7

Sembra che posso scrivere una where x.a==1 && x.b==1 comeQual è la differenza tra più clausole where e && operator in LINQ-to-SQL?

where x.a==1 
where x.b==1 

quanto ho capito questo si trasforma in .Where(x => x.a == 1).Where(x => x.b ==1), ma come si traduce questo al DB? Quale sarebbe migliore in termini di ottimizzazione? Posso sempre osservare la query eseguita da profiler, ma difficilmente si tratta di una generalizzazione, ma più come una singola osservazione empirica, su cui non voglio fare affidamento.

Passare attraverso lo spazio dei nomi System.Linq con riflettore è un'altra opzione, ma in tal caso perdere l'opportunità di salvare molte persone dal trascorrere del tempo sulla stessa cosa. Lo farò se non avrò risposte.

+2

quasi duplicato di http://stackoverflow.com/questions/1648730/when-using-linq-what-is-the-difference-between-and-multiple-where-clauses –

+0

Non l'ho trovato nel mio ricerca ma questo è specifico LINQ-to-SQL. –

+0

l'impatto su LINQ-to-Objects sarebbe ovvio, tuttavia LINQ-to-SQL non è chiaro. –

risposta

7

Ok ecco i miei risultati dopo aver passato l'uscita Reflector per un po '. LINQ to Objects combinare i consecutivi where predicati quando si utilizza WhereArrayIterator o WhereListIterator inducendolo a QUASI comportarsi come & & operatore, ma non come esattamente:

Quando si utilizza x.a==1 && x.b==1 la clausola WHERE si traduce in un Func<TSource, bool> simile a questo:

bool daspredicate(TSource x) 
{ 
    return x.a==1 && x.b==1 
} 

Tuttavia, quando si utilizzano clausole Where consecutive c'è una leggera penalizzazione delle prestazioni, almeno dall'aspetto IL non JITted.Ecco come il codice si presenta come dopo la combinazione:

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); 
} 

Come si può vedere si tratta di un ulteriore sovraccarico funzione di chiamata. Questo può essere piuttosto costoso a meno che JIT non indichi le funzioni. Sono sicuro che fa un buon lavoro ma ora sappiamo che il lavoro di JIT diventa molto più facile se uniamo le nostre dichiarazioni Where, a meno che non sia necessario.

Sul lato SQL, tuttavia, le query sono le stesse. Anche prima dell'esecuzione, il debugger valuta l'oggetto query nella stessa istruzione SQL. Non potevo andare troppo lontano nello spazio dei nomi di Linq perché le cose sembravano molto più complesse, ma poiché le query sono le stesse, non dovrebbe esserci alcuna penalità diversa dall'esempio LINQ-to-objects sopra.

MODIFICA: ho visto le istanze in cui più istruzioni in cui risultano sottospecifiche annidate su server SQL. Penso che sia meglio attenersi al singolo in cui le dichiarazioni ogni volta che si può essere dalla parte della sicurezza.

2

Spetta a LINQ to SQL fare la cosa giusta qui. Mi aspetto che converta due clausole "where" in una singola clausola SQL con le due parti unite insieme a "AND".

Provate entrambi, ma dubito molto che vedrete qualche differenza nell'SQL generato.

IMO si dovrebbe sempre guardare l'SQL generato per qualcosa di non banale, ma il modo in cui funziona LINQ certamente incoraggia di costruire una query di grandi dimensioni componendo fuori di piccole clausole - quindi mi piacerebbe davvero aspettare solo a lavoro.

+0

Sembra, grazie! –

2

lato DB sono identici. È solo un effetto collaterale di Linq-to-SQL che è componibile (ad esempio, è possibile iniziare con una query e aggiungere ulteriori criteri, cambiare le proiezioni, ecc.).

2

Il codice:

where x.a==1 
where x.b==1 

o

where x.a==1 && x.b==1 

è zucchero sintattico per C# in ogni caso. Si compilerà come metodo catena di LINQ di

Where(...).Where(...) 

proprio come avete indovinato probabilmente sarebbe, quindi ho davvero dubbio v'è alcuna differenza nel codice SQL generato. Prova a usare uno strumento come Resharper di Jetbrains: offre persino intellisense che ti dà la possibilità di auto-convertirti tra i due per risparmiare tempo a riscriverlo per il test.

La mia preferenza è scrivere query molto semplici come catene di metodi, (ad esempio, dove c'è solo 1 collezione/tabella coinvolta e nessun join) e nulla di più complicato nella più espressiva sintassi zucchero di Linq.

+0

Apparentemente non sono molto identici, vedi la mia risposta. –

Problemi correlati