2012-06-21 22 views
12

Dopo aver letto this domanda, Ho bisogno di chiarire alcune cose.IEnumerable <T> e IQueryable <T> chiarimenti?

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; 

Domande:

1) è ok per dire che: nella prima query SQLServer è in esecuzione l'intera operazione, compreso dove clausola e ritorno SOLO le righe rilevanti - mentre il secondo fa SELECT * ... e restituisce tutte le righe in C# e THEN filtri?

2) Che dire se ho una raccolta solo - in 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; 

quale sarà la differenza di esecuzione ora?

+0

Dai un'occhiata a questo argomento pertinente: http://stackoverflow.com/questions/252785/quello-è-differenza-dall'interno-di-questionatore-and-ienumerablet. E inoltre, hai ragione nel presupposto in # 1. Non sicuro al 100% di # 2, quindi lo lascerò a un altro. – blizz

+0

@blizz l'ho già letto. tutte le risposte ci sono da un libro POV. niente rispondendo alla mia domanda lì ....: (... mal sia ** felice ** per vedere quale linea risponde alla mia domanda –

risposta

29

1: No, che non è corretto

Dal momento che si sta solo memorizzare il dato in IEnumerable<Customer>, ma hanno ancora la stessa identica espressione che produce il risultato, essi saranno entrambi eseguire sul server e restituire solo le righe pertinenti.

Si otterrebbe la differenza di comportamento con questo:

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

In questo caso si sta forzando la collezione db.Customers da utilizzare come IEnumerable<T>, che quando enumerato scaricherà l'intera collezione.

noti che questo:

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

non è lo stesso di questo:

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

Nel primo caso, la clausola where sarà una parte del SQL, nel secondo ha vinto 't. Questo è il motivo per cui la domanda/risposta collegata comporta una differenza, mentre il tuo codice no.

Si noti inoltre che solo le affermazioni che sono state scritte non eseguiranno di fatto nulla sul server, dal momento che memorizzeranno effettivamente solo una raccolta lenta. Se si va avanti e si elencano tali raccolte, a quel punto i bit rilevanti verranno eseguiti sul server.

2: List<T> non implementa o hanno metodi di estensione per IQueryable<T>, né gli operatori LINQ coinvolto nulla di ritorno compatibile con IQueryable<T>

In questo caso, il primo non verrà compilato.

+0

così (nel mio link) driis ha sbagliato nella sua risposta? –

+0

No, come ho detto, loro entrambi eseguiranno la stessa operazione, tuttavia, nel caso del codice collegato, l'operatore LINQ "Dove" viene applicato a "IEnumerable " o "IQueryable ", è stata aggiunta una clausola 'where' alla query originale. Questo cambia l'ordine delle operazioni, quindi nel tuo caso, esse eseguiranno allo stesso modo. Nella risposta collegata, non lo saranno. –

+0

riguardo _forcing della collezione db.Customers da utilizzare come IEnumerable , che al momento dell'enumerazione preleverà il intera raccolta_, se ho capito bene, questo codice otterrà TUTTI I CLIENTI e POI Filtro? –

Problemi correlati