2010-08-17 19 views
8

ho questo:Qual è la differenza tra IOrderedQueryable e IQueryable?

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

e questo:

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

Pur comprendendo l'uso di entrambi (e uno genera un errore in seguito) non capisco come sono diversi.

Ho visto domande come questa altrove su STO, ma non ho raccolto la risposta a questa domanda, temo.

+1

Puoi mostrare il codice che mostra l'errore. – Lazarus

risposta

4

Un tipo che implementa IOrderedQueryable<T> contiene uno stato aggiuntivo per contenere informazioni sull'ordinamento.

IQueryable<T> rappresenta normalmente un'operazione che verrà eseguita in un secondo momento (e possibilmente in un linguaggio completamente diverso su un altro computer, ad esempio con LINQ su SQL). È necessaria un'interfaccia separata perché la prossima operazione potrebbe essere un altro tipo, che deve essere trattato in modo diverso rispetto al primo (per ordinare per colonna A e poi B richiede due operatori LINQ per definire, ma il sistema deve garantire che ogni chiave contribuisca a il tipo generale).

+1

Non sono sicuro che sia corretto, poiché l'interfaccia IOrderedQueryable è solo un'interfaccia marker (vedere http://msdn.microsoft.com/en-us/library/bb340178.aspx). Quindi immagino che contenga solo le informazioni che l'elenco è ordinato, ma non altre informazioni sull'ordinamento stesso. – Gerwald

+0

@leo: se un provider LINQ specifico utilizza questo come un marcatore (e consentendo successive chiamate 'ThenBy' /' ThenByDescending') o se l'oggetto restituito è veramente diverso è un dettaglio di implementazione. In LINQ to Objects è un tipo diverso (prova a fare la tua implementazione), ma chiaramente altri provider (ad esempio per generare SQL) avranno approcci molto diversi. Riepilogo: consente a un provider di adottare un'implementazione diversa per gli operatori di ordinamento, ma non li richiede. – Richard

0

IOrderedQueryable il risultato di una query che risulta in un ordine specifico e IQueryable ha elementi in un ordine indeterminato.

+0

Ho ragione nel ritenere che il primo esempio di codice non ordini nulla? In tal caso, che senso ha essere in grado di usare 'orderby' prima di' where'? –

+0

@ Matt-W: dovremmo esaminare l'albero delle espressioni per determinare in che modo specificamente ogni query viene elaborata. Sospetto che sia la prima query a generare l'errore per te. Non sarebbe la prima o l'unica query di Linq che si può scrivere e compilare felicemente senza errori che poi falliscono durante l'esecuzione, questa è la natura di Linq. – Lazarus

2

È facile vedere se si traduce la comprensione della query nei suoi corrispondenti metodi di estensione Linq. Il tipo di reso di OrderBy() è IOrderedEnumerable <>. Dove() restituisce IEnumerable <>. Quello che fa la tua prima espressione è prima di tutto tutti i dei Punti, quindi seleziona solo quelli che corrispondono alla clausola where. L'ultima operazione applicata è Dove, quindi il tipo di espressione è IEnumerable <>.

Quale è più efficiente dipende in gran parte dal provider Linq che si utilizza. I miei soldi sono ordinati per ultimi. Anche se immagino che il fornitore sia abbastanza intelligente da ordinare le operazioni nel miglior ordine. Potresti volerlo controllare.

Problemi correlati