2012-06-21 32 views
12

Después de leer this pregunta, Necesito aclarar algunas cosas.IEnumerable <T> y IQueryable <T> aclaración?

IQueryable<Customer> custs = from c in db.Customers 
where c.City == "<City>" 
select c; 

IEnumerable<Customer> custs = from c in db.Customers 
where c.City == "<City>" 
select c; 

Preguntas:

1) ¿Es correcto decir que: en la primera consulta del SQL Server se está ejecutando la operación entera incluyendo la cláusula dónde y regresar SOLO las filas relevantes - mientras que el segundo lo hace SELECT * ... y devuelve todas las filas en C# y THEN filtros?

2) ¿Qué pasa si tengo colección simplemente - en la memoria. (var lstMyPerson = new List<MyPerson>())

IQueryable<MyPerson> lst = from c in lstMyPerson 
where c.City == "<City>" 
select c; 

vs

IEnumerable<MyPerson> custs = from c in lstMyPerson 
where c.City == "<City>" 
select c; 

lo que será la diferencia en la ejecución ahora?

+0

Eche un vistazo a este tema relevante: http://stackoverflow.com/questions/252785/what-is-the-difference-between-iqueryablet-and-ienumerablet. Y también, tienes razón en tu suposición en el # 1. No estoy 100% seguro sobre el n. ° 2 así que lo dejo a otro. – blizz

+0

@blizz ya lo leí. todas las respuestas son de un libro POV. nada respondiendo mi pregunta allí ...: (... estaré ** feliz ** para ver qué línea responde mi pregunta –

Respuesta

29

1: No, eso no es correcto

Dado que sólo está almacenando el resultado en un IEnumerable<Customer>, pero todavía tienen la misma expresión exacta que produce el resultado, ellos ambos se ejecutan en el servidor y devuelve solo las filas relevantes.

Obtendría la diferencia de comportamiento con esto:

IEnumerable<Customer> custs = from c in (IEnumerable<Customer>)db.Customers 
    where c. City == "<City>" 
    select c; 

En este caso estás forzando la colección db.Customers para ser utilizado como IEnumerable<T>, que cuando se enumeró se ha podido ir a la colección completa.

Tenga en cuenta que esto:

IEnumerable<Customer> x = from c in db.Customers 
          where c.City == "<City>" 
          select c; 

no es lo mismo que esto:

IEnumerable<Customer> x = from c in db.Customers 
          select c; 
IEnumerable<Customer> y = x.Where(c => c.City == "<City>"); 

En el primer caso, la cláusula where será una parte del SQL, en el segundo se ganó 't. Es por eso que la pregunta/respuesta vinculada implica una diferencia, mientras que su código no lo hace.

También tenga en cuenta que solo las afirmaciones que ha escrito no ejecutarán nada en absoluto en el servidor, ya que de hecho solo almacenan una colección perezosa. Si continúa y enumera esas colecciones, en ese punto, los bits relevantes se ejecutarán en el servidor.

2: List<T> no implementa o tienen métodos de extensión para IQueryable<T>, ni los operadores involucrados LINQ devuelve nada compatible con IQueryable<T>

En este caso, la primera no se compilará.

+0

entonces (en mi enlace) driis tiene un error en su respuesta? –

+0

No, como dije, Ambos harán lo mismo. Sin embargo, en el caso del código vinculado, el operador 'Where' LINQ se aplica al' IEnumerable 'o al' IQueryable ', ha agregado una cláusula' where' a la consulta original. Esto cambia el orden de las operaciones, por lo que en su caso, se ejecutarán de la misma manera. En la respuesta vinculada, no lo harán. –

+0

con respecto a _forzar la colección db.Customers que se utilizará como IEnumerable , que cuando se enumere obtendrá el colección completa_, si entendí correctamente, este código obtendrá TODOS LOS CLIENTES y luego FILTRAR? –

Cuestiones relacionadas