2010-10-31 14 views
13

En mi consulta necesito devolver IEnumerable pero no sé si esta acción hace que la consulta se ejecute de nuevo?convierte IQueryable a IEnumerable ejecutar la consulta de nuevo?

var data = Repository<Person>.Find().AsEnumerable();

Find() vuelve IQueryable y porque IQueryable hereda IEnumerable. Dudo si AsEnumerable hace la ejecución repetitiva.

Sé que var data = Repository<Person>.Find().ToList() ejecuta la consulta dos veces. Uno para Find() y segundo para Tolist()

Respuesta

20

Un IQueryable es un IEnumerable. No hay conversión y, por lo tanto, no se está realizando ningún tipo de trabajo.

El trabajo ocurre cuando llama al GetEnumerator(), ya sea explícitamente o invocando foreach en él.

Además, ¿ha confirmado que Repository.Find().ToList() llama a SQL dos veces? Eso no me suena bien.

+0

Para hacer esto más correcto. IQueryable no es un IEnumerable ... pero hereda de él. - http://stackoverflow.com/questions/2433306/whats-the-difference-between-iqueryable-and-ienumerable – Jimmyt1988

+1

@ Jimmyt1988 https://en.wikipedia.org/wiki/Is-a#Examples_of_subtyping –

11

AsEnumerable en realidad no hace nada excepto aplicar el operador as a su IQueryable. En consecuencia, cualquier método futuro que aplique a su objeto utilizará System.Linq.Enumerable set de métodos de extensión en lugar de los métodos System.Linq.Queryable.

Todo se trata de ejecución diferida. Nunca se ejecuta nada en contra de su fuente consultable (la base de datos presumiblemente) hasta que intente enumerar.

En otras palabras:

var data=Repository.Find().AsEnumerable() 
/* The query is only actually performed AFTER here */ 
.ToList(); 

Si su código:

var data=Repository.Find().ToList(); 

ejecuta la consulta dos veces, es porque estás haciendo algo incorrecto en el método Find(), que sin duda debe no debería ser el caso.

var data = Respository.Find(); 

debe ejecutar la consulta ZERO veces.

var result = data.ToList(); // THIS is what should execute the query. 
+0

tenías razón tenía tolist() al final del método de búsqueda y no lo noté. – Adrakadabra

1

pensar en linq como un "Stream" y la función de agregado es un "Flush". La transmisión "linq a db" solo puede descargar una vez. .AsEnumerable(), .Where(), .... es una forma de preparar la consulta .ToList(), .First(), .Max() es un agregado pero si no lo llama agrega, entonces su linq resultado no se ejecutará. comienza a funcionar solo cuando se lo enumera.

ex

var result = users.Select(usr => usr.Name); 

no pasará nada aquí hasta

1 agregada se llama

result.First() 

o 2 resultado es ser enumerar

result.ToList().ForEach(...) 

para responder a yout pregunta - .Find(), .AsEnumerable() no es una función de agregado

Cuestiones relacionadas