¿Cuál es la diferencia entre IQueryable e IEnumerable?


Respuestas:


186

IEnumerable<T>representa un cursor de solo avance de T. .NET 3.5 agregó métodos de extensión que incluyeron LINQ standard query operatorssimilares Wherey First, con cualquier operador que requiera predicados o funciones anónimas Func<T>.

IQueryable<T>implementa los mismos operadores de consulta estándar de LINQ, pero acepta Expression<Func<T>>predicados y funciones anónimas. Expression<T>es un árbol de expresión compilado, una versión desglosada del método ("medio compilado" si lo desea) que el proveedor del consultable puede analizar y usar en consecuencia.

Por ejemplo:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

En el primer bloque, x => x.Age > 18hay un método anónimo ( Func<Person, bool>), que se puede ejecutar como cualquier otro método. Enumerable.Whereejecutará el método una vez para cada persona, yielding valores para los cuales el método regresó true.

En el segundo bloque, x => x.Age > 18hay un árbol de expresión ( Expression<Func<Person, bool>>), que se puede considerar como "es la propiedad 'Edad'> 18".

Esto permite que existan cosas como LINQ-to-SQL porque pueden analizar el árbol de expresión y convertirlo en SQL equivalente. Y debido a que el proveedor no necesita ejecutar hasta que IQueryablese enumere ( IEnumerable<T>después de todo, se implementa ), puede combinar múltiples operadores de consulta (en el ejemplo anterior Wherey FirstOrDefault) para tomar decisiones más inteligentes sobre cómo ejecutar la consulta completa contra los datos subyacentes fuente (como usar SELECT TOP 1en SQL).

Ver:


1
respuesta bastante breve
ashveli

83

En la vida real, si está utilizando un ORM como LINQ-to-SQL

  • Si crea un IQueryable, entonces la consulta puede convertirse a sql y ejecutarse en el servidor de base de datos
  • Si crea un IEnumerable, todas las filas se extraerán en la memoria como objetos antes de ejecutar la consulta.

En ambos casos, si no se llama a una ToList()o ToArray()a continuación, la consulta será ejecutado cada vez que se utiliza, por lo que, por ejemplo, usted tiene una IQueryabley llenar 4 cuadros de lista de él, entonces la consulta se ejecuta en la base de datos 4 veces.

Además, si extiende su consulta:

q.Select(x.name = "a").ToList()

Luego, con un IQueryableSQL generado, contendrá where name = "a", pero con IEnumerablemuchos más roles se retirará de la base de datos, luego x.name = "a".NET realizará la verificación.


"la consulta puede convertirse a sql": no obtuve el 'puede ser'. Además, si tengo un IEnumerable y creo una 'cadena compleja', entonces (obviamente) a diferencia de IQueryable, no se traducirá en una consulta SQL 'optimizada'. Solo quiero confirmar lo que significa cuando dices 'todas las filas se extraerán en la memoria'. Digamos que tengo dos cláusulas where, entonces todas las tuplas de las entidades se recuperarán primero en la memoria y luego se producirá el filtrado normal 'en memoria'.
Vaibhav

36

"La principal diferencia es que los métodos de extensión definidos para IQueryable toman objetos Expression en lugar de objetos Func, lo que significa que el delegado que recibe es un árbol de expresión en lugar de un método para invocar. IEnumerable es excelente para trabajar con colecciones en memoria, pero IQueryable permite para una fuente de datos remota, como una base de datos o un servicio web "

Fuente: aquí


19

IEnumerable IEnumerable es el más adecuado para trabajar con la recopilación en memoria. IEnumerable no se mueve entre elementos, solo se reenvía la colección.

IQueryable IQueryable se adapta mejor a la fuente de datos remota, como una base de datos o un servicio web. IQueryable es una característica muy poderosa que permite una variedad de escenarios de ejecución diferida interesantes (como consultas basadas en paginación y composición).

Entonces, cuando solo tiene que recorrer la colección en memoria, use IEnumerable, si necesita hacer alguna manipulación con la colección como Dataset y otras fuentes de datos, use IQueryable


11

La principal diferencia es que IEnumerable enumerará todos sus elementos todo el tiempo, mientras que IQueryable enumerará elementos, o incluso hará otras cosas, en función de una consulta. La consulta es una Expresión (una representación de datos del código .Net), que un IQueryProvider debe explorar / interpretar / compilar / lo que sea para generar resultados.

Tener una expresión de consulta ofrece dos ventajas.

La primera ventaja es la optimización. Debido a que modificadores como 'Where' están incluidos en la expresión de consulta, IQueryProvider puede aplicar optimizaciones imposibles de otro modo. En lugar de devolver todos los elementos y luego desechar la mayoría de ellos debido a una cláusula 'Dónde', el proveedor podría usar una tabla hash para ubicar elementos con una clave determinada.

La segunda ventaja es la flexibilidad. Debido a que las expresiones son estructuras de datos explorables, puede hacer cosas como serializar la consulta y enviarla a una máquina remota (por ejemplo, linq-to-sql).



1

En primer lugar, IEnumerable se encuentra en un espacio de nombres System.Collections mientras que IQueryable se encuentra en un espacio de nombres System.Linq. Si usa IEnumerable cuando consulta datos de colecciones en memoria como List, Array collection, etc. Y cuando consulta datos de colecciones fuera de memoria (como base de datos remota, servicio), entonces use IQueryable. Porque Al consultar datos de la base de datos, IEnumerable ejecuta una consulta de selección en el lado del servidor, carga los datos en la memoria en el lado del cliente y luego filtra los datos. Por lo tanto, hace más trabajo y se vuelve lento. Mientras consulta datos de la base de datos, IQueryable ejecuta una consulta de selección en el lado del servidor con todos los filtros. Por lo tanto, trabaja menos y se vuelve rápido.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.