2013-02-12 8 views
14

Sono un po 'novizio su .NET, e mi chiedevo come funziona linq, dal momento che puoi inserire molte query di linq, una dopo l'altra, ma nessuna di esse viene realmente eseguita fino a quando non vengono utilizzate per trasferire informazioni o convertite in elenco, ecc.
Esistono due modi importanti per ottenere una query linq, utilizzando IQueryable<T>, che applica i filtri Where direttamente a Sql e IEnumerable che ottiene tutti i record e quindi li utilizza in memoria. Tuttavia, diamo un'occhiata a questo codice:Convertire una query Iqeryable su linq IEnumerable <T> annulla il modo ottimizzato per lavorare su linq?

  //Linq dynamic library 
      IQueryable<Table> myResult = db.Categories 
       .Where(a => a.Name.Contains(StringName)) 
       .OrderBy("Name") 
       .Skip(0) 
       .Take(10); 

      if (myResult != null) 
      { 
       return myResult.AsEnumerable(); 
      } 
      else 
      { return null; } 

Nonostante i lavori sto utilizzando libreria dinamica Linq, il risultato diretto da questa query è essere get on IQueryable<T>, se la query viene finalmente restituito come IEnumerable, è il la query viene realmente filtrata in SQL? o è in memoria?

+1

Il modo migliore per rispondere è guardare la proprietà 'Log' del contesto dati e vedere di persona. Sperimenta diverse varianti sulla tua query e osserva come influisce su ciò che è * effettivamente * eseguito. – Servy

+0

Mi dispiace, come posso controllare il registro? –

+1

Bene, questa è probabilmente una buona domanda per Google o la documentazione MSDN per quella proprietà di quel tipo; se la memoria serve c'è un buon esempio lì. – Servy

risposta

28

È ancora in esecuzione nel database, non preoccuparti. Fondamentalmente è tutto a cui viene applicata l'implementazione di Where ecc. Mentre stai chiamando i metodi su IQueryable<T> - tramite i metodi di estensione Queryable - utilizzeranno gli alberi di espressione. Quando si avvia a preleva da quella query, verrà convertito in SQL e inviato al database.

D'altra parte, se si utilizza uno qualsiasi di questi metodi dopo ce l'hai come IEnumerable<T> (in termini di tipo in fase di compilazione), che utilizzerà i metodi di estensione in Enumerable, e tutti il resto dell'elaborazione farebbe in-process.

A titolo di esempio, si consideri questo:

var query = db.People 
       .Where(x => x.Name.StartsWith("J")) 
       .AsEnumerable() 
       .Where(x => x.Age > 20); 

Qui AsEnumerable()solo restituisce la sua sequenza di input, ma digitato come IEnumerable<T>. In questo caso, la query del database restituirebbe solo le persone il cui nome iniziò con J - e quindi il filtro dell'età sarebbe stato eseguito sul client.

+1

Grazie mille per le risposte! hanno aiutato molto! –

4

Se si restituisce un IEnumerable<T> e quindi si raffina ulteriormente la query, l'ulteriore perfezionamento si verifica in memoria. La parte che è stata espressa su un IQueryable<T> verrà convertita nelle istruzioni SQL appropriate (per il caso LINQ-to-SQL, ovviamente).

Vedere Returning IEnumerable<T> vs. IQueryable<T> per una risposta più lunga e dettagliata.