2014-04-09 10 views
7

Ho bisogno di capire questo. C'è una grande differenza tra EF5.0 e EF6 * in TSQL di generazione di codiceEntityFramework LINQToEntities generano uno strano lento TSQL Where-Clause

Nel mio codice questo è il mio LINQ -. Statemant

var qry2 = context.viw_overview_1.Where(i => i.article_EAN17 == ean).Select(i => i.article_id).Take(200); 

EntityFramework 5,0 generano solo un TSQL semplice e veloce DOVE - dichiarazione come questa, che è perfetto

... WHERE [Extent1].[article_EAN17] = @p__linq__0 
00.0960096ms in SSMS 

ma EntityFramework 6. * generare una dichiarazione molto più complesso e lento

... WHERE (([Extent1].[article_EAN17] = @p__linq__0) AND (NOT ([Extent1].[article_EAN17] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[article_EAN17] IS NULL) AND (@p__linq__0 IS NULL)) 
45.3665362ms in SSMS 

il campo articolo_EAN17 ha anche un indice. tuttavia EF6. * Impiega comunque l'età per inizializzarsi, MA c'è un modo per generare una semplice istruzione WHERE in EF6. * Con attributi o qualcosa del genere? Ho provato string.Equals(), string.Compare(), scambiando il parametro, ma non è cambiato nulla.

Why does Entity Framework 6 generate complex SQL queries for simple lookups? spiegare la differenza, Ma c'è un modo per forzare EF a generare TSQL semplice.

+1

Dubito che il cambiamento T-SQL stia rallentando. Hai provato entrambe le query sullo stesso set di dati? – haim770

+1

Solo curioso: hai schiaffeggiato le due dichiarazioni in SSMS e confrontato le loro prestazioni? –

+0

il semplice confronto di EF5 è 5 volte più veloce di EF6 in C# e molto più veloce in SSMS – Roland

risposta

8

Credo che questo è legato alle impostazioni di confronto NULL in Entity Framework

aggiungere il seguente codice prima della query per vedere se aiuta le prestazioni di query:

context.ContextOptions.UseCSharpNullComparisonBehavior = true; 
+1

Non è false di default? http://msdn.microsoft.com/en-us/library/system.data.entity.core.objects.objectcontextoptions.usecsharpnullcomparisonbehavior(v=vs.113).aspx – IronMan84

+3

actual è 'context.Configuration.UseDatabaseNullSemantics = true; 'thx to MattC – Roland

+0

Appena aggiornato la risposta. scusa per l'errore di battitura. – mmilleruva

1

Se è assolutamente, bisogno positivamente per fare in modo che il controllo nullo aggiunto venga interrotto, è sempre possibile utilizzare DbSet.SqlQuery() (documentazione here) per configurare manualmente la query (e tutti i parametri) che si desidera venga eseguita. Fai attenzione, però, perché a volte quel metodo può funzionare in modi che non ti aspetti. Se non vuoi/hai bisogno di tracciamento puoi usare anche (documentazione here), che ti permetterà di usare i generici anche con la tua query (altrimenti dovrai lanciarlo).

Personalmente preferirei lasciarlo da solo o utilizzare stored procedure, come @EricScherrer menzionato nei commenti.