Solución:
IEnumerable<T>
representa un cursor de solo avance de T
. .NET 3.5 agregó métodos de extensión que incluían el LINQ standard query operators
igual que Where
y First
, con cualquier operador que requiera predicados o funciones anónimas tomando Func<T>
.
IQueryable<T>
implementa los mismos operadores de consulta estándar LINQ, pero acepta Expression<Func<T>>
para predicados y funciones anónimas. Expression<T>
es un árbol de expresión compilado, una versión dividida del método (“medio compilado” si lo desea) que puede ser analizado por el proveedor de la consulta y utilizado 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 > 18
es un método anónimoFunc<Person, bool>
), que se puede ejecutar como cualquier otro método. Enumerable.Where
ejecutará el método una vez para cada persona, yield
ing valores para los que el método devolvió true
.
En el segundo bloque, x => x.Age > 18
es un árbol de expresiónExpression<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 expresiones y convertirlo en SQL equivalente. Y debido a que el proveedor no necesita ejecutar hasta que IQueryable
está enumerado (implementa IEnumerable<T>
, después de todo), puede combinar varios operadores de consulta (en el ejemplo anterior Where
y FirstOrDefault
) para tomar decisiones más inteligentes sobre cómo ejecutar la consulta completa contra la fuente de datos subyacente (como usar SELECT TOP 1
en SQL).
Ver:
- Los operadores de consulta estándar de .NET
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 la base de datos - Si crea un
IEnumerable
, entonces todas las filas se colocarán en la memoria como objetos antes de ejecutar la consulta.
En ambos casos, si no llama a un ToList()
o ToArray()
luego, la consulta se ejecutará cada vez que se use, por lo que, por ejemplo, tiene un IQueryable
y llena 4 cuadros de lista, luego la consulta se ejecutará en la base de datos 4 veces.
Además, si amplía su consulta:
q.Select(x.name = "a").ToList()
Luego con un IQueryable
el SQL generado contendrá where name = "a"
, pero con un IEnumerable
muchos más roles serán retirados de la base de datos, luego x.name = "a"
La verificación se realizará mediante .NET.
“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í