Jaka jest różnica między IQueryable<T>
i IEnumerable<T>
?
Zobacz także Jaka jest różnica między IQueryable i IEnumerable, która pokrywa się z tym pytaniem.
źródło
Jaka jest różnica między IQueryable<T>
i IEnumerable<T>
?
Zobacz także Jaka jest różnica między IQueryable i IEnumerable, która pokrywa się z tym pytaniem.
Przede wszystkim, rozciąga się interfejs, więc coś można zrobić z „zwykły” , można również zrobić z .IQueryable<T>
IEnumerable<T>
IEnumerable<T>
IQueryable<T>
IEnumerable<T>
tylko ma GetEnumerator()
metody, która zwraca Enumerator<T>
na której można wywołać jego MoveNext()
metodę iterację sekwencji T .
To IQueryable<T>
, czego IEnumerable<T>
nie ma, to w szczególności dwie właściwości - jedna, która wskazuje na dostawcę zapytań (np. Dostawca LINQ na SQL), a druga wskazuje na wyrażenie zapytania reprezentujące IQueryable<T>
obiekt jako abstrakcyjne drzewo składni, które można przenosić w czasie wykonywania. zrozumiałe dla danego dostawcy zapytań (w przeważającej części nie można podać wyrażenia LINQ do SQL dostawcy LINQ do podmiotu bez zgłoszenia wyjątku).
Wyrażenie może być po prostu stałym wyrażeniem samego obiektu lub bardziej złożonym drzewem złożonego zestawu operatorów zapytań i operandów. Dostawca IQueryProvider.Execute()
lub IQueryProvider.CreateQuery()
metody zapytania są wywoływane z przekazanym do niego wyrażeniem , a następnie IQueryable
zwracany jest odpowiednio wynik zapytania lub inny .
AsQueryable()
po prostu rzutuje wyliczenie na kwerendę i zwraca ją, jeśli implementujeIQueryable
interfejs, w przeciwnym razie zawija go wConstantExpression
, do którego odwołuje się zwróconyEnumerableQuery
obiekt.Podstawowa różnica polega na tym, że operatory LINQ do
IQueryable<T>
pobieraniaExpression
obiektów zamiast delegatów, co oznacza, że otrzymywana przez nie niestandardowa logika zapytań, np. Predykat lub selektor wartości, ma postać drzewa wyrażeń zamiast delegata do metody.IEnumerable<T>
jest świetny do pracy z sekwencjami, które są iterowane w pamięci, aleIQueryable<T>
pozwala na brak pamięci, takie jak zdalne źródło danych, takie jak baza danych lub usługa internetowa.Wykonanie zapytania:
W przypadku, gdy wykonanie zapytania będzie wykonywane „w toku” , zwykle wszystko, czego potrzeba, to kod (jako kod) do wykonania każdej części zapytania.
Tam, gdzie wykonanie zostanie wykonane poza procesem , logika zapytania musi być reprezentowana w danych, tak aby dostawca LINQ mógł przekonwertować go na odpowiednią formę do wykonania braku pamięci - niezależnie od tego, czy jest to zapytanie LDAP, SQL lub cokolwiek innego.
Więcej w:
IEnumerable<T>
iIQueryable<T>
IEnumerable<T>
vsIQueryable<T>
”IEnumerable
,IQueryable
,IObservable
, iIQbservable
źródło
To fajne wideo na youtube, które pokazuje, jak różne są te interfejsy, warte obejrzenia.
Poniżej znajduje się długa opisowa odpowiedź na to pytanie.
Pierwszą ważną kwestią do zapamiętania jest
IQueryable
dziedziczenie interfejsuIEnumerable
, więc cokolwiekIEnumerable
może zrobić,IQueryable
może również zrobić.Istnieje wiele różnic, ale omówmy jedną wielką różnicę, która stanowi największą różnicę.
IEnumerable
Interfejs jest przydatny, gdy twoja kolekcja jest ładowana za pomocąLINQ
lub Entity Framework i chcesz zastosować filtr do kolekcji.Rozważ poniższy prosty kod, który wykorzystuje się
IEnumerable
w ramach encji. UżywaWhere
filtra, aby uzyskać rekordy, którychEmpId
jest2
.To, gdzie filtr jest wykonywany po stronie klienta, gdzie
IEnumerable
znajduje się kod. Innymi słowy wszystkie dane są pobierane z bazy danych, a następnie na jego klient skanuje i pobiera rekordEmpId
jest2
.Ale teraz patrz poniższy kod zmieniliśmy
IEnumerable
sięIQueryable
. Tworzy zapytanie SQL po stronie serwera i tylko niezbędne dane są wysyłane po stronie klienta.Różnica między
IQueryable
iIEnumerable
dotyczy tego, gdzie wykonywana jest logika filtru. Jeden wykonuje po stronie klienta, a drugi w bazie danych.Więc jeśli pracujesz tylko z gromadzeniem danych w pamięci,
IEnumerable
to dobry wybór, ale jeśli chcesz zapytać o zbieranie danych, które jest połączone z bazą danych, `IQueryable jest lepszym wyborem, ponieważ zmniejsza ruch w sieci i wykorzystuje moc języka SQL.źródło
IEnumerable: IEnumerable najlepiej nadaje się do pracy z kolekcją w pamięci (lub zapytaniami lokalnymi). IEnumerable nie przemieszcza się między elementami, jest tylko kolekcją do przodu.
IQueryable: IQueryable najlepiej nadaje się do zdalnego źródła danych, takiego jak baza danych lub usługa internetowa (lub zdalne zapytania). IQueryable to bardzo potężna funkcja, która umożliwia szereg interesujących scenariuszy odroczonego wykonania (takich jak zapytania stronicowania i oparte na kompozycji).
Więc jeśli musisz po prostu iterować kolekcję w pamięci, użyj IEnumerable, jeśli potrzebujesz wykonać dowolną manipulację z kolekcją, taką jak Zbiór danych i inne źródła danych, użyj IQueryable
źródło
Innymi słowy, inną istotną różnicą jest to, że IEnumerable wykonuje zapytanie selekcyjne po stronie serwera, ładuje dane do pamięci po stronie klienta, a następnie filtruje dane, podczas gdy IQueryable wykonuje zapytanie selekcyjne po stronie serwera ze wszystkimi filtrami.
źródło
W prawdziwym życiu, jeśli używasz ORM, takiego jak LINQ-to-SQL
W obu przypadkach, jeśli nie nazywamy
ToList()
lubToArray()
wówczas zapytanie wykonywane za każdym razem, gdy jest używany, więc, powiedzmy, maszIQueryable<T>
i wypełnić 4 Wykaz pól od niego, wtedy zapytanie zostanie uruchomione na bazie 4-krotnie.Również jeśli rozszerzysz swoje zapytanie:
Następnie z IQueryable wygenerowany SQL będzie zawierał „gdzie nazwa =„ a ”, ale przy IEnumerable wiele innych ról zostanie wycofanych z bazy danych, a następnie sprawdzenie .x.name =„ a ”zostanie wykonane przez .NET.
źródło
IEnumerable odnosi się do kolekcji, ale IQueryable jest tylko zapytaniem, które zostanie wygenerowane w drzewie wyrażeń. Uruchomimy to zapytanie, aby uzyskać dane z bazy danych.
źródło
Poniższy mały test może pomóc zrozumieć jeden aspekt różnicy między
IQueryable<T>
iIEnumerable<T>
. Powtórzyłem tę odpowiedź z tego postu, w którym próbowałem dodać poprawki do postu innej osobyUtworzyłem następującą strukturę w DB (skrypt DDL):
Oto skrypt wstawiania rekordów (skrypt DML):
Teraz moim celem było po prostu uzyskanie 2 najlepszych rekordów z
Employee
tabeli w bazie danych. Dodałem element ADO.NET Entity Data Model do mojej aplikacji konsoli wskazując naEmployee
tabelę w mojej bazie danych i zacząłem pisać zapytania LINQ.Kod trasy IQueryable :
Kiedy zacząłem uruchamiać ten program, rozpocząłem także sesję profilowania zapytań SQL na mojej instancji SQL Server i oto podsumowanie wykonania:
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
Po prostu
IQueryable
jest wystarczająco inteligentny, aby zastosowaćTop (2)
klauzulę po stronie samego serwera bazy danych, dzięki czemu łączy tylko 2 z 5 rekordów. Dalsze filtrowanie w pamięci nie jest wcale wymagane po stronie komputera klienckiego.Kod dla IEnumerable route :
Podsumowanie wykonania w tym przypadku:
SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]
Teraz
IEnumerable
przyniesiono wszystkie 5 rekordów obecnych wSalary
tabeli, a następnie przeprowadzono filtrowanie w pamięci na komputerze klienckim, aby uzyskać 2 najlepsze rekordy. Tak więc więcej danych (w tym przypadku 3 dodatkowe rekordy) zostało niepotrzebnie przesłanych przewodowo.źródło
Oto, co napisałem w podobnym poście (na ten temat). (I nie, zwykle nie cytuję siebie, ale są to bardzo dobre artykuły).
„Ten artykuł jest pomocny: IQueryable vs IEnumerable w LINQ-to-SQL .
Cytując ten artykuł: „Zgodnie z dokumentacją MSDN wywołania w IQueryable działają w oparciu o wewnętrzne drzewo wyrażeń. „Te metody, które rozszerzają IQueryable (Of T), nie wykonują żadnych zapytań bezpośrednio. Zamiast tego ich funkcją jest zbudowanie obiektu Expression, który jest drzewem wyrażeń reprezentującym zapytanie skumulowane.”
Drzewa wyrażeń są bardzo ważną konstrukcją w języku C # i na platformie .NET. (Są one ogólnie ważne, ale C # czyni je bardzo przydatnymi.) Aby lepiej zrozumieć różnicę, zalecam przeczytanie o różnicach między wyrażeniami i wyrażeniami w oficjalnej specyfikacji C # 5.0 tutaj. W przypadku zaawansowanych koncepcji teoretycznych, które rozgałęziają się w rachunku lambda, wyrażenia umożliwiają obsługę metod jako obiektów pierwszej klasy. Różnica między IQueryable i IEnumerable skupia się wokół tego punktu. IQueryable buduje drzewa wyrażeń, podczas gdy IEnumerable nie działa, przynajmniej ogólnie dla tych z nas, którzy nie pracują w tajnych laboratoriach Microsoft.
Oto kolejny bardzo przydatny artykuł, który wyszczególnia różnice z perspektywy push and pull. (Przez „push” vs. „pull” mam na myśli kierunek przepływu danych. Reaktywne techniki programowania dla .NET i C #
Oto bardzo dobry artykuł, który szczegółowo opisuje różnice między wyrażeniem lambdas a wyrażeniem lambdas i omawia pojęcia warkocza wyrażeń bardziej szczegółowo: Ponowne odwiedzanie delegatów C #, drzew wyrażeń i wyrażeń lambda vs. wyrażeń lambda. . ”
źródło
Używamy
IEnumerable
iIQueryable
manipulujemy danymi pobieranymi z bazy danych.IQueryable
dziedziczy poIEnumerable
, więcIQueryable
zawiera wszystkieIEnumerable
funkcje. Główną różnicą pomiędzyIQueryable
iIEnumerable
jestIQueryable
Wykonuje kwerendy z filtrami natomiastIEnumerable
wykonuje zapytanie, a następnie filtruje dane w oparciu o warunki.Znajdź bardziej szczegółowe zróżnicowanie poniżej:
IEnumerable
IEnumerable
istnieje wSystem.Collections
przestrzeni nazwIEnumerable
wykonaj wybrane zapytanie po stronie serwera, załaduj dane do pamięci po stronie klienta, a następnie przefiltruj daneIEnumerable
jest odpowiedni do tworzenia zapytań o dane ze zbiorów w pamięci, takich jak List, ArrayIEnumerable
jest korzystny dla zapytań LINQ to Object i LINQ to XMLIQueryable
IQueryable
istnieje wSystem.Linq
przestrzeni nazwIQueryable
wykonuje „wybierz zapytanie” po stronie serwera ze wszystkimi filtramiIQueryable
nadaje się do wysyłania zapytań o dane z kolekcji zewnętrznych (takich jak zdalna baza danych, usługa)IQueryable
jest korzystny dla zapytań LINQ do SQLIEnumerable
Jest więc ogólnie używany do radzenia sobie z kolekcją w pamięci, podczas gdyIQueryable
jest ogólnie używany do manipulowania kolekcjami.źródło
Zarówno IEnumerable, jak i IQueryable służą do przechowywania kolekcji danych i wykonywania operacji manipulacji danymi, na przykład filtrowania kolekcji danych. Tutaj możesz znaleźć najlepsze porównanie różnic z przykładem. http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html
źródło
IQueryable jest szybszy niż IEnumerable, jeśli mamy do czynienia z ogromnymi ilościami danych z bazy danych, ponieważ IQueryable pobiera tylko wymagane dane z bazy danych, gdzie jako IEnumerable pobiera wszystkie dane bez względu na konieczność z bazy danych
źródło
ienumerable: kiedy chcemy poradzić sobie z pamięcią wewnętrzną, tzn. bez połączenia danych iqueryable: kiedy mamy do czynienia z serwerem sql, tj. z ilistem połączenia danych: operacje takie jak dodawanie obiektu, usuwanie obiektu itp
źródło