2012-06-21 22 views
12

Po przeczytaniu this pytania, Muszę wyjaśnić pewne rzeczy.IEnumerable <T> i IQueryable <T> wyjaśnienie?

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; 

Pytania:

1) jest to ok, aby powiedzieć, że: w pierwszym zapytaniu SQLServer pracuje całą operację w tym wyrażeniu WHERE i powrocie TYLKO odpowiednich rzędach - podczas gdy drugi robi SELECT * ... i zwraca wszystkie wiersze na C# i THEN filtrów?

2) A jeśli mam tylko kolekcję - w pamięci. (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; 

jaka będzie różnica w wykonaniu teraz?

+0

Zobacz odpowiedni temat: http://stackoverflow.com/questions/252785/what-is-the-difference-between-iqueryablet-and-ienumerablet. A także, masz rację w swoim założeniu w # 1. Nie jestem w 100% pewien co do drugiego, więc zostawię go innemu. – blizz

+0

@blizz już to przeczytałem. wszystkie odpowiedzi pochodzą z książki POV. nic nie odpowiada na moje pytanie ...: (... niech będzie ** szczęśliwy **, żeby zobaczyć, która linia odpowiada na moje pytanie –

Odpowiedz

29

1: Nie, to jest błędne

Skoro tylko przechowywania wynik w na IEnumerable<Customer>, ale nadal mają dokładnie ten sam wyraz, który powoduje ten efekt, będą one wykonywać zarówno na serwerze i zwraca tylko odpowiednie wiersze.

co można uzyskać różnicę w zachowaniu z tym:

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

w tym przypadku zmuszają kolekcję db.Customers być stosowany jako IEnumerable<T>, który po wyliczone pobierze całą kolekcję.

Należy zauważyć, że w ten sposób:

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

nie jest taki sam jak ten:

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

w pierwszym przypadku, klauzula where będzie częścią SQL, w drugim wygrał "t. Dlatego powiązane pytanie/odpowiedź zawiera różnicę, a twój kod nie.

Należy również pamiętać, że napisane przez ciebie wyciągi nie będą w rzeczywistości wykonywać niczego na serwerze, ponieważ będą one skutecznie przechowywać tylko leniwą kolekcję. Jeśli przejdziesz dalej i wyliczysz te zbiory, w tym momencie odpowiednie bity zostaną wykonane na serwerze.

2: List<T> nie realizuje lub mieć metody rozszerzenie dla IQueryable<T>, ani też operatorzy LINQ zaangażowany nic powrotny zgodny z IQueryable<T>

W tym przypadku, pierwszy nie będzie skompilować.

+0

, więc (w moim linku) driis ma złą odpowiedź w swojej odpowiedzi? –

+0

Nie, jak powiedziałem, oni Oba będą robić to samo, jednak w przypadku połączonego kodu, operator 'LINQ' Gdzie jest stosowany do 'IEnumerable ' lub 'IQueryable ', dodajesz klauzulę 'where' do pierwotnego zapytania. Zmienia to kolejność operacji, więc w twoim przypadku będą one wykonywane w ten sam sposób.W połączonej odpowiedzi nie będą one miały wartości –

+0

dotyczące _forcing kolekcji db.Customers do użycia jako IEnumerable , która po wyliczeniu pobierze Cała kolekcja_, jeśli rozumiem poprawnie, ten kod dostanie WSZYSTKICH KLIENTÓW, A NASTĘPNIE Filtr? –

Powiązane problemy