Domanda

Sono confuso per quanto riguarda la differenza. Essendo abbastanza nuovo per .Net, so di poter interrogare IEnumerables utilizzando le estensioni Linq. Così che cosa è questo IQueryable e come si differenziano?


Si veda anche Qual è la differenza tra IQueryable [T] e IEnumerable [T]? che si sovrappone a questa domanda.

È stato utile?

Soluzione

IEnumerable<T> rappresenta un cursore di inoltro solo di T. NET 3.5 ha aggiunto metodi di estensione che includevano il LINQ standard query operators come Where e First, con tutti gli operatori che richiedono predicati o funzioni anonime che prendono Func<T>.

IQueryable<T> implementa gli operatori di query standard stesso LINQ, ma accetta Expression<Func<T>> per predicati e funzioni anonime. Expression<T> è un albero di espressione compilata, una versione broken-up del metodo ( "half-compilato" se si vuole) che può essere analizzato dal fornitore al queryable e utilizzato di conseguenza.

Ad esempio:

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();

Nel primo blocco, x => x.Age > 18 è un metodo anonimo (Func<Person, bool>), che può essere eseguito come qualsiasi altro metodo. Enumerable.Where eseguirà il metodo una volta per ogni persona, i valori per i quali il metodo restituito yield trueing.

Nel secondo blocco, x => x.Age > 18 è un albero di espressione (Expression<Func<Person, bool>>), che può essere pensato come "è il 'Age' proprietà> 18".

In questo modo le cose come LINQ to SQL di esistere perché possono analizzare l'albero di espressione e convertirlo in SQL equivalente. E perché il provider non ha bisogno di eseguire fino a quando viene enumerato l'IQueryable (implementa IEnumerable<T>, dopo tutto), è possibile combinare più operatori di query (nel nostro esempio Where e FirstOrDefault) a fare scelte più intelligenti su come eseguire l'intera query contro l'origine dati sottostante (come l'utilizzo SELECT TOP 1 in SQL).

See:

Altri suggerimenti

Nella vita reale, se si utilizza un ORM come LINQ to SQL

  • Se si crea un IQueryable, quindi la query può essere convertito in SQL ed eseguire sul server di database
  • Se si crea un IEnumerable, quindi tutte le righe saranno tirati in memoria come oggetti prima di eseguire la query.

In entrambi i casi, se non si chiamare un ToList() o ToArray() allora interrogazione verrà eseguita ogni volta che viene utilizzato, in modo, ad esempio, si dispone di un IQueryable e si riempie di 4 caselle di riepilogo da esso, allora la query verrà eseguito a fronte del database 4 volte.

Anche se si estende la query:

q.Select(x.name = "a").ToList()

Poi, con un IQueryable l'SQL generato conterrà where name = "a", ma con un IEnumerable molti altri ruoli saranno tirato indietro dal database, quindi il controllo x.name = "a" sarà fatto da NET.

"La differenza principale è che i metodi di estensione definiti per IQueryable prendono Espressione oggetti anziché oggetti Func, significa il delegato che riceve è un albero di espressione invece di un metodo per invocare. IEnumerable è grande per lavorare con raccolte in memoria, ma IQueryable consente una fonte di dati a distanza, come un database o web service "

Fonte: qui

IEnumerable IEnumerable calza meglio per lavorare con la raccolta in memoria. IEnumerable non si muove tra gli elementi, è avanti solo di raccolta.

IQueryable IQueryable meglio si adatta per l'origine dei dati a distanza, come un servizio di database o web. IQueryable è una caratteristica molto potente che permette una varietà di interessanti scenari di esecuzione differita (come la paginazione e query composizione a base).

Quindi, quando si dispone di iterare semplicemente attraverso la raccolta in memoria, utilizzare IEnumerable, se avete bisogno di fare alcuna manipolazione con la raccolta, come set di dati e altre fonti di dati, usare IQueryable

Il principio di differenza è che IEnumerable enumererà tutti i suoi elementi per tutto il tempo, mentre IQueryable enumererà elementi, o anche fare altre cose, sulla base di una query. La query è un'espressione (una rappresentazione di dati di codice Net), che un IQueryProvider deve esplorare / interpretare / compilare / tutto ciò al fine di generare risultati.

Avere un'espressione di query dà due vantaggi.

Il primo vantaggio è l'ottimizzazione. Perché i modificatori come 'dove' sono inclusi nella espressione di query, l'IQueryProvider può applicare ottimizzazioni altrimenti impossibili. Invece di restituire tutti gli elementi poi gettare via la maggior parte di loro a causa di un 'dove' la clausola, il provider potrebbe utilizzare una tabella hash per individuare gli elementi con una data chiave.

Il secondo vantaggio è la flessibilità. Perché Le espressioni sono strutture di dati esplorabili, si possono fare cose come serializzare la query e inviarlo a un computer remoto (ad es. LINQ to SQL).

IQueriable è lo stesso di IEnumerable ma fornisce anche funzionalità aggiuntive per implementare personalizzati interrogazione con LINQ. Qui è la descrizione su MSDN: http://msdn.microsoft. com / it-it / library / system.linq.iqueryable.aspx

Innanzitutto IEnumerable si trovano in una System.Collections namespace mentre l'IQueryable si trovano in una System.Linq Namespace. Se siete uso IEnumerable quando si interroga i dati provenienti da collezioni in memoria come elenco, raccolta Array ecc E quando l'interrogazione dei dati provenienti da fuori-memoria (come database remoto, di servizio) raccolte in modo che siano usare IQueryable. Perché mentre l'interrogazione dei dati dal database, IEnumerable eseguire query di selezione sul lato server, caricare i dati in memoria sul lato client e quindi filtrare i dati. fa quindi più lavoro e diventa lento. Mentre interrogazione dei dati dal database, IQueryable eseguire query di selezione sul lato server con tutti i filtri. fa quindi meno lavoro e diventa veloce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top