IEnumerable<T>
representa un cursor de solo avance de T
. .NET 3.5 agregó métodos de extensión que incluyeron LINQ standard query operators
similares Where
y 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 > 18
hay un método anónimo ( Func<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 cuales el método regresó true
.
En el segundo bloque, x => x.Age > 18
hay 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 IQueryable
se enumere ( IEnumerable<T>
después de todo, se implementa ), puede combinar múltiples operadores de consulta (en el ejemplo anterior Where
y FirstOrDefault
) para tomar decisiones más inteligentes sobre cómo ejecutar la consulta completa contra los datos subyacentes fuente (como usar SELECT TOP 1
en SQL).
Ver: