2010-08-17 13 views
8

tengo esto:¿Cuál es la diferencia entre IOrderedQueryable y IQueryable?

var points = from p in ContextDB.Points 
       orderby p.PointInTime descending 
       where p.InstanceID == instanceId 
       && p.ParentPointID == null 
       && p.PointTypeID == currentPointTypeID 
       select p; 

y esto:

var points = from p in ContextDB.Points 
       where p.InstanceID == instanceId 
       && p.ParentPointID == null 
       && p.PointTypeID == currentPointTypeID 
       orderby p.PointInTime descending 
       select p; 

Si bien entiendo el uso de ambos (y uno genera un error más adelante) no entiendo cómo son diferentes.

He visto preguntas como esta en otros lugares de STO, pero no he recogido cuál es la respuesta a esta pregunta, me temo.

+1

Puede mostrar el código que muestra el error. – Lazarus

Respuesta

4

Un tipo que implementa IOrderedQueryable<T> contiene un estado adicional para almacenar información sobre la clasificación.

IQueryable<T> normalmente representa una operación que se realizará más tarde (y posiblemente en un idioma completamente diferente en una computadora diferente, por ejemplo, con LINQ a SQL). Se necesita una interfaz separada porque la próxima operación podría ser de otro tipo, que debe tratarse de manera diferente a la primera (ordenar por columna A y luego B requiere dos operadores LINQ para definir, pero el sistema debe asegurarse de que cada clave contribuya a el tipo general).

+1

No estoy seguro de si esto es correcto, ya que la interfaz IOrderedQueryable es solo una interfaz de marcador (ver http://msdn.microsoft.com/en-us/library/bb340178.aspx). Así que supongo que solo contiene la información de que la lista está ordenada, pero ninguna otra información sobre la clasificación en sí misma. – Gerwald

+0

@leo: Si un proveedor de LINQ específico usa esto como marcador (y permite las siguientes llamadas 'ThenBy' /' ThenByDescending') o si el objeto devuelto es realmente diferente es un detalle de implementación. En LINQ to Objects es un tipo diferente (intente hacer su propia implementación), pero claramente otros proveedores (por ejemplo, para generar SQL) tendrán enfoques muy diferentes. Resumen: da la posibilidad de que un proveedor tome una implementación diferente para los operadores de clasificación, pero no lo requiere. – Richard

0

IOrderedDetecte el resultado de una consulta que dé como resultado un orden específico e IQueryable tenga elementos en un orden indeterminado.

+0

¿Estoy en lo cierto al pensar que la primera muestra de código no ordenará nada? Si es así, ¿cuál es el sentido de poder usar 'orderby' antes de' where'? –

+0

@ Matt-W: Tendríamos que mirar el árbol de expresiones para determinar cómo se procesa específicamente cada consulta. Sospecho que es la primera consulta que genera el error para ti. No sería la primera o la única consulta de Linq que puede escribir y compilar sin errores que luego falla durante la ejecución, esa es la naturaleza de Linq. – Lazarus

2

Es fácil de ver si traduce la comprensión de la consulta a sus métodos de extensión Linq correspondientes. El tipo de devolución de OrderBy() es IOrderedEnumerable <>. Donde() devuelve IEnumerable <>. Lo que hace su primera expresión es primero ordenar todos de los puntos, luego seleccione solo los que coincidan con la cláusula where. La última operación aplicada es Donde, por lo tanto, el tipo de expresión es IEnumerable <>.

Cuál es más eficiente depende en gran medida del proveedor de Linq que utilice. Mi dinero está en clasificar el último. Aunque supongo que el proveedor es lo suficientemente inteligente como para ordenar las operaciones en el mejor orden. Es posible que desee comprobar eso.

Cuestiones relacionadas