Jaka jest różnica między IQueryable a IEnumerable

Jestem zdezorientowany co do różnicy. Jako całkiem nowy w. Net, wiem, że mogę odpytywać IEnumerables za pomocą rozszerzeń Linq. Co to jest IQueryable i czym się różni?


Zobacz także Jaka jest różnica między IQueryable[T] i IEnumerable[T]?To pokrywa się z tym pytaniem.

Author: Community, 2010-03-12

7 answers

IEnumerable<T> reprezentuje kursor T Tylko do przodu. . NET 3.5 dodał metody rozszerzeń, które zawierały LINQ standard query operators, takie jak Where i First, z dowolnymi operatorami wymagającymi predykatów lub funkcji anonimowych przyjmującymi Func<T>.

IQueryable<T> implementuje te same standardowe operatory zapytań LINQ, ale akceptuje Expression<Func<T>> dla predykatów i funkcji anonimowych. Expression<T> jest skompilowanym drzewem wyrażeń, podzieloną wersją metody ("Half-compiled", jeśli chcesz), która może być parsowana przez dostawcę queryable i stosowane odpowiednio.

Na przykład:

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

W pierwszym bloku x => x.Age > 18 jest anonimowa metoda (Func<Person, bool>), która może być wykonywana jak każda inna metoda. Enumerable.Where wykona metodę raz dla każdej osoby, yield ing wartości, dla których metoda zwróciła true.

W drugim bloku x => x.Age > 18 jest drzewem wyrażeń (Expression<Func<Person, bool>>), które można traktować jako "is the' Age 'property > 18".

Pozwala to na istnienie takich rzeczy jak LINQ-to-SQL, ponieważ mogą one analizować drzewo wyrażeń i przekonwertować go na odpowiednik SQL. A ponieważ dostawca nie musi wykonywać, dopóki IQueryable nie zostanie wyliczony (implementuje IEnumerable<T>), może łączyć wiele operatorów zapytań (w powyższym przykładzie Where i FirstOrDefault), aby dokonać mądrzejszych wyborów, jak wykonać całe zapytanie w oparciu o źródło danych (jak użycie SELECT TOP 1 w SQL).

Zobacz:

 189
Author: Richard Szalay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-01 20:41:23

W rzeczywistości, jeśli używasz ORM jak LINQ-to-SQL

  • jeśli utworzysz IQueryable, wtedy zapytanie może zostać przekonwertowane na sql i uruchomione na serwerze bazy danych
  • jeśli utworzysz IEnumerable, wszystkie wiersze zostaną pobrane do pamięci jako obiekty przed uruchomieniem zapytania.

W obu przypadkach jeśli nie wywołasz ToList() lub ToArray() wtedy zapytanie będzie wykonywane za każdym razem, gdy zostanie użyte, więc powiedzmy, że masz IQueryable i wypełnisz z niego 4 pola listy, wtedy zapytanie zostanie uruchomione przeciwko bazie danych 4 razy.

Również w przypadku rozszerzenia zapytania:

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

Następnie z IQueryable wygenerowany SQL będzie zawierał where name = "a", ale z IEnumerable o wiele więcej ról zostanie wycofanych z bazy danych, następnie x.name = "a" sprawdzenie zostanie wykonane przez .NET.

 85
Author: Ian Ringrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-27 14:40:28

" podstawowa różnica polega na tym, że metody rozszerzenia zdefiniowane dla IQueryable przyjmują Obiekty wyrażenia zamiast obiektów Func, co oznacza, że delegat, który otrzymuje, jest drzewem wyrażeń zamiast metody do wywołania. IEnumerable jest świetny do pracy ze zbiorami w pamięci, ale IQueryable pozwala na zdalne źródło danych, takie jak Baza Danych lub serwis internetowy "

Źródło: TUTAJ

 36
Author: Gabe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 14:24:37

IEnumerable IEnumerable najlepiej nadaje się do pracy z kolekcji in-memory. IEnumerable nie porusza się między przedmiotami, jest tylko kolekcją do przodu.

IQueryable IQueryable najlepiej pasuje do zdalnego źródła danych, jak Baza Danych lub serwis internetowy. IQueryable to bardzo potężna funkcja, która umożliwia wiele ciekawych scenariuszy odroczonego wykonania (takich jak stronicowanie i zapytania oparte na kompozycji).

Więc kiedy trzeba po prostu iterację poprzez In-memory collection, use IEnumerable, if you need to do any manipulation with the collection like Dataset and other data sources, use IQueryable

 19
Author: Talha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-10 11:27:57

Zasadnicza różnica polega na tym, że IEnumerable wyliczy wszystkie swoje elementy przez cały czas, podczas gdy IQueryable wyliczy elementy, a nawet zrobi inne rzeczy na podstawie zapytania. Zapytanie jest wyrażeniem (reprezentacja danych kodu. Net), które IQueryProvider musi zbadać/zinterpretować/skompilować / cokolwiek, aby wygenerować wyniki.

Posiadanie wyrażenia zapytania daje dwie zalety.

Pierwszą zaletą jest optymalizacja. Ponieważ modyfikatory typu "Gdzie" są zawarte w wyrażenie zapytania, IQueryProvider może zastosować w przeciwnym razie niemożliwe optymalizacje. Zamiast zwracać wszystkie elementy, a następnie wyrzucać większość z nich z powodu klauzuli "gdzie", dostawca może użyć tabeli hash do zlokalizowania elementów z danym kluczem.

Drugą zaletą jest elastyczność. Ponieważ wyrażenia są strukturami danych, które można badać, można wykonać takie czynności, jak serializacja zapytania i wysłanie go na zdalną maszynę(np. linq-to-sql).

 11
Author: Craig Gidney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-06 13:48:01

Przestrzenie nazw kolekcji, podczas gdy IQueryable znajdują się w systemie.Przestrzeń Nazw Linq. Jeśli używasz IEnumerable podczas odpytywania danych z kolekcji in-memory, takich jak List, Array collection itp. oraz podczas odpytywania danych z kolekcji out-memory (takich jak remote database, service), więc używasz IQueryable. Ponieważ podczas odpytywania danych z bazy danych, IEnumerable wykonuje zapytanie select po stronie serwera, ładuje dane w pamięci po stronie klienta, a następnie filtruje dane. Stąd robi więcej pracy i staje się powolny. Podczas odpytywania danych z bazy danych, IQueryable wykonuje zapytanie select po stronie serwera ze wszystkimi filtrami. Stąd robi mniej pracy i staje się szybki.

 2
Author: Nayeem Mansoori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-12 05:18:33

IQueriable jest taki sam jak IEnumerable, ale zapewnia również dodatkową funkcjonalność do implementacji niestandardowych zapytań za pomocą Linq. Oto opis MSDN: http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx

 1
Author: Andrew Bezzub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 14:24:09