¿Cuál es la diferencia de IEnumerable e IQueryable? .Net C# VB

Cuando comenzamos a utilizar Entity Framework vemos la maravilla de LINQ al obtener los datos de manera relacional, organizarlos como si de Sql se tratara, pero nunca nos preguntamos que de distinto tiene cuando utilizamos IQueryable o IEnumerable, para explicarlo rápidamente nos basaremos en la siguiente tabla (suponiendo que su nombre es tabla, literal):

Cuando obtenemos los datos con IEnumerable de la siguiente forma:


IEnumerable<tabla> lst= from d in db.tabla
                 select d;

Si quisiéramos hacer un filtrado con una clausula where posterior a nuestra obtención de datos haríamos lo siguiente:


lst= lst.Where(d=&gt;d.name=='Pedro');

Cuando utilizamos IEnumerable al llenar nuestro objeto con LINQ lo que obtenemos son los datos de la tabla en nuestra colección es decir, que al aplicar el filtrado trabajamos directamente con un conjunto de datos en memoria al cual se le hace el where directamente. Esto ocasiona un mal performance cuando nuestra tabla tiene millones de datos ya que los tendríamos en memoria y posterior aplicaríamos el filtrado, esto es una mala practica que jamas se debe hacer.

Ahora veamos la diferencia con IQueryable:


IQueryable<tabla> lst= from d in db.tabla
                 select d;

//lo que obtiene IQueryable despues de la consulta es:
// select * from tabla

Ahora haremos el mismo filtro posterior a la consulta:


lst= lst.Where(d=>d.name=='Pedro');

//y aquí lo que hacemos es concatenarle:
select * from tabla where name='Pedro'

A diferencia de IEnumerable lo que tenemos en nuestro objeto IQueryable es la consulta SQL en sí, es decir tenemos algo como lo siguiente:


select * from tabla
where name='Pedro'

En conclusión si vamos a realizar filtrados dinámicos en un conjunto de datos se debe utilizar la interface IQueryable, es la forma correcta de aplicar manipulación a nuestra consulta antes de enviarla al servidor de base de datos. ¿Cuando se realizar el envió de la consulta al servidor por parte de IQueryable? Cuando hacemos uso de los datos es decir, cuando aplicamos un foreach o hacemos un ToList().

Linq, introducción y ejemplos rápidos en C# .Net

Esta entrada hablare sobre LINQ, lo necesario para que comprendas fácilmente y rápido, sin tanta teoría ni palabras raras.

Linq nació por allá del 2008 y desde entonces nos ha facilitado la vida, ya que agrega funcionalidades al lenguaje de c# o Visual Basic .Net respecto cualquier almacen de datos, es decir, nos permite aplicar algo parecido a consultas de SQL a una lista, un xml, o ¿porque no?, a la misma base de datos.
Algo que el mismo Microsoft recalca en todos sus cursos es que Linq se divide en tres acciones que son:

  1. Obtención de origen de datos.
  2. Creación de la consulta
  3. Ejecución de la consulta.

Terminemos de la palabrería y vayamos a los ejemplos.

El primer ejemplo es cómo podemos ordenar una lista de enteros con Linq y se puede hacer de la siguiente manera.

1. Obtención de origen de datos:

 int[] arregloEnteros = { 1, 2, 3, 5, 3, 2, 8, 9 };

2. Creación de la consulta

 
IEnumerable<int> lstEnterosOrdenados = from nums in arregloEnteros 
                                       orderby nums 
                                       select nums;

En este punto aún no se ejecuta la consulta solo la guardamos en este caso en una colección de la instancia IEnumerable. Cualquier tipo de dato que admita implícitamente la interfaz IEnumerable o alguna de sus derivaciones, se le puede aplicar LINQ.

3. Ejecución de la consulta (ahora si aquí se ejecuta la magia de LINQ)

 

foreach(int n in lstEnterosOrdenados){      
 Console.WriteLine(n);            
}

De esta manera nuestro resultado es el siguiente:

linq1

Como vemos de una manera rápida podemos realizar operaciones que son el pan de cada día.

Ahora veamos otros ejemplos para comprender mejor el alcance de LINQ:

Filtrar elementos

 
//Origen de datos 
int[] arregloEnteros = { 1, 2, 3, 5, 3, 2, 8, 9 }; 

//Consulta, utilizamos where como en sql para obtener numeros menores a 5 

IEnumerable<int> lstEnterosMenoresCinco = from nums in arregloEnteros                                                      
                                          where nums < 5                                                      
                                          select nums;

//Ejecucion 
foreach (int n in lstEnterosMenoresCinco) {         
            Console.WriteLine(n); 
}
linq2

Linq en elementos complejos


//clase Complejo, una clase que nos servirá para el ejemplo
 public class Complejo
        {
             public int numero{get;set;}
             public string cadena{get;set;}

             public Complejo(int numero, string cadena)
             {
                 this.numero = numero;
                 this.cadena = cadena;
             }

             public string imprime()
             {
                 return numero + " " + cadena;
             }
        }

          

//origen de datos            
Complejo[] lstComplejos={ 
new Complejo(1,"pato"),                                   
new Complejo(5,"perro"),                                      
new Complejo(9,"pajaro"),                                      
new Complejo(10,"pez"),                                      
new Complejo(2,"ave"),                                      
new Complejo(4,"gusano"),                                    
};       

//consulta            
IEnumerable<Complejo> lstComplejosConP =from d in lstComplejos                                                  
where d.cadena.StartsWith("p")                                                    select d;            

//ejecución de consulta            
foreach(Complejo c in lstComplejosConP){                  
   Console.WriteLine(c.imprime());            

}

linq3

Linq en elementos complejos obtener una colección reducida

//utilizamos la misma clase Complejo

//origen de datos            
Complejo[] lstComplejos={ 
new Complejo(1,"pato"),                                      
new Complejo(5,"perro"),                                      
new Complejo(9,"pajaro"),                                      
new Complejo(10,"pez"),                                      
new Complejo(2,"ave"),                                      
new Complejo(4,"gusano"),                                    
};

//Consulta, reducimos la clase Complejo a una lista de cadenas

IEnumerablex lstSoloCadenas = from d in lstComplejos
select d.cadena; 

//ejecución de consulta   

foreach (string s in lstSoloCadenas){
   
    Console.WriteLine(s);    

}

linq4

Con esto es más que suficiente para que hayan entendido LINQ y su potencial, de aquí en adelante solo les queda practicar y ver lo practico que es esta característica en .Net.