2009-09-18 17 views
6

Bien, necesito un control de cordura aquí ...¿Cuándo se ejecuta una consulta compilada que devuelve IQueryable?

He compilado una consulta que devuelve un IQueryable cuando se ejecuta.

¿En qué línea (s) debe ejecutarse realmente la consulta en la base de datos en el siguiente ejemplo?

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

Aquí es como defino la consulta compilada

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

para una discusión adicional, consulte: LINQ to SQL compiled queries and when they execute

Respuesta

2

"en la línea 104, al hacer la conversión ToList."

Bueno, esta respuesta es incorrecta. Invocamos al delegado almacenado en la variable MyCompiledQuery en la línea 101 que devuelve el resultado de la consulta compilada, no la consulta en sí.

+0

No hay ninguna declaración en la línea 104. Intente establecer un punto de interrupción allí ... – Guffa

+0

Creo que esta consulta realmente se ejecuta en la línea 101 (incluso antes de llamar a ToList). – lahsrah

+0

No. La línea 101 crea una consulta. La consulta se ejecuta cuando se obtienen los datos reales. – alex

2

Se ejecuta en la línea 104 (cuando llama a ToList()).

Una consulta compilada es una consulta que se traduce solo una vez a TSQL en tiempo de compilación, en lugar de cada vez antes de la ejecución.

+0

No hay ninguna declaración en la línea 104. Intente establecer un punto de interrupción allí ... – Guffa

+0

Tiene razón, pero está dividiendo los pelos. El ToList está en la línea 104, no en el 102. Esta no es una pregunta capciosa, y quería saber si compilar la consulta significa que se ejecuta inmediatamente, sin que una de las 3 líneas sea una declaración. – Alan

+0

Me gustaría pensar que se ejecuta en 102/104, pero cuando ejecuto un depurador y un Analizador de SQL, veo una instrucción SQL ejecutada después de que se ejecuta 101 y luego 12 sentencias SQL (una para cada resultado en 101) ejecutan en 102/104 –

0

Esto se denomina Ejecución diferida.
Puede leer una buena publicación en ella here.

+0

Sí, eso es lo que pensé y cómo diseñé mi aplicación. Sin embargo, cuando la aplicación ejecuta la línea 101, veo una instrucción SQL volando en el Analizador de SQL, y luego otra declaración SQL para cada resultado devuelto por la línea 101. –

+0

Puedo confirmar lo que Antilogic publicó. La consulta se ejecuta en la línea 101 – lahsrah

+0

@Antilogic: el proceso de compilación de la consulta puede necesitar información sobre la estructura de la base de datos, pero no recupera ningún dato en esa etapa. Si lo hiciera, no obtendría nada más adelante cuando use el resultado. – Guffa

1

Esta consulta se ejecuta en la línea 101. Lo verifiqué haciendo un rastreo del Analizador de SQL. Supongo que esto se debe a que es una consulta compilada.

El filtrado que está haciendo después> 5 se realiza en la memoria.

+0

-1 Comprueba la traza de nuevo. Puede haber algo de tráfico si se necesita información sobre la estructura de la base de datos, pero la consulta real no se ejecuta compilando. Esta página, por ejemplo, establece claramente que puede proporcionar valores de parámetros después de compilar la consulta, lo que no sería posible si la consulta también se ejecutó: http://msdn.microsoft.com/en-us/library/bb896297.aspx – Guffa

+0

Llamar al método de consulta compilada hace que la consulta se ejecute en la base de datos. Lo he comprobado varias veces con una base de datos simple. Por supuesto, puede pasar los valores de los parámetros, no estoy diciendo que la compilación hace que se ejecute, estoy diciendo que llamar al método de consulta compilado hace que se ejecute y ** no ** el método .ToList(). – lahsrah

0

Por lo que sé IQueryable nunca se ejecuta simplemente convierte la consulta de Linq a un formato consultable para que se ejecute cada vez que se solicite.

En este caso, supongo que en el momento en que se le solicita convertir en una lista, consulta el resultado. Y no tiene sentido luchar en la línea 102 y 104 ya que ambos representan una sola línea.

Cuestiones relacionadas