2009-09-18 10 views
6

Okay Ho bisogno di un controllo di integrità qui ...Quando viene eseguita una query compilata che restituisce un esecuzione IQueryable?

Ho compilato una query che restituisce un IQueryable quando eseguito.

Su quale riga (i) deve essere eseguita effettivamente la query sul database nel seguente esempio?

101 IQueryable<T> results = MyCompiledQuery(MyDataContext); 
102 List<T> final = (from t in result 
103     where t.ID > 5 
104     select t).ToList<T>(); 

Ecco come io definisco la query compilata

public static Func<MyDataContext, IQueryable<Widget>> MyCompiledQuery= 
     CompiledQuery.Compile<MyDataContext, IQueryable<Widget>>(
         (MyDataContext db) => 
         from w in db.Widgets 
         where ((w.Type == WidgetType.Atype || //Widget.Atype is a Linq to Sql object, that I've defined statically 
           w.Type == WidgetType.Btype || //See above comment 
           w.Type == WidgetType.Ctype) && //See above comment 
           w.Location == WidgetLocation.Domestic) //Samething applies here 
         select euc); 

PER DISCUSSIONE ULTERIORI fare riferimento a: "Sulla linea 104, quando si fa la conversione ToList" LINQ to SQL compiled queries and when they execute

risposta

2

Bene, questa risposta non è corretta. Invochiamo il delegato archiviato nella variabile MyCompiledQuery sulla riga 101 che restituisce il risultato della query compilata, non la query stessa.

+0

Non c'è alcuna istruzione alla riga 104. Prova a impostare un punto di interruzione ... – Guffa

+0

Penso che questa query venga effettivamente eseguita sulla riga 101 (anche prima di chiamare ToList). – lahsrah

+0

No. La riga 101 crea una query. La query viene eseguita quando vengono recuperati i dati effettivi. – alex

2

Viene eseguito alla riga 104 (quando si chiama ToList()).

Una query compilata è una query che viene tradotta una sola volta in TSQL in fase di compilazione, anziché ogni volta prima dell'esecuzione.

+0

Non c'è un'istruzione alla riga 104. Prova a impostare un punto di interruzione lì ... – Guffa

+0

Hai ragione, ma stai dividendo i capelli. ToList è sulla linea 104, non 102. Questa non è una domanda trabocchetto, e voleva sapere se la compilazione della query significa che viene immediatamente eseguita, non che le 3 righe sono un'affermazione. – Alan

+0

Mi piacerebbe pensare che venga eseguito a 102/104 ma quando eseguo un debugger e SQL Profiler, vedo un'istruzione SQL eseguita dopo 101 esecuzioni e quindi 12 istruzioni SQL (una per ogni risultato su 101) eseguite a 102/104 –

0

Questo è chiamato Esecuzione posticipata.
È possibile leggere un buon post su di esso here.

+0

Sì, questo è quello che pensavo e come ho progettato la mia applicazione. Tuttavia, quando l'app esegue la riga 101, vedo volare un'istruzione SQL in SQL Profiler e quindi un'altra istruzione SQL per ogni risultato restituito dalla riga 101. –

+0

Posso confermare che cosa ha postato Antilogic. La query viene eseguita sulla riga 101 – lahsrah

+0

@Antilogic: il processo di compilazione della query potrebbe richiedere informazioni sulla struttura del database, ma non recupera alcun dato in quella fase. Se lo facesse, non recupererebbe nulla più tardi quando si usa il risultato. – Guffa

1

Questa query viene eseguita sulla riga 101. L'ho verificata eseguendo una traccia di SQL Profiler. Immagino sia perché è una query compilata.

Il filtro che si sta facendo afterwords> 5 viene eseguito in memoria.

+0

-1 Controllare di nuovo la traccia. Potrebbe esserci del traffico se sono necessarie informazioni sulla struttura del database, ma la query effettiva non viene eseguita compilandola. Questa pagina, ad esempio, indica chiaramente che è possibile fornire i valori dei parametri dopo aver compilato la query, operazione che non sarebbe possibile se la query fosse eseguita anche: http://msdn.microsoft.com/en-us/library/bb896297.aspx – Guffa

+0

La chiamata al metodo di query compilato fa sì che la query venga eseguita sul database. L'ho controllato più volte con un semplice database. Ovviamente puoi passare i valori dei parametri, non sto dicendo che la compilazione lo faccia eseguire, sto dicendo che chiamare il metodo di query compilato lo fa eseguire e ** non ** il metodo .ToList(). – lahsrah

0

Per quanto ne so IQueryable non viene mai eseguito, converte la query Linq in un formato interrogabile in modo che venga eseguita ogni volta che viene richiesta.

In questo caso, suppongo che nel momento in cui è stato chiesto di convertire in un elenco, interroga il risultato. E nessun punto in lotta per la linea 102 e 104 poiché entrambi rappresentano una singola riga.

Problemi correlati