IEnumerable<T>
reprezentuje kursor tylko do przodu T
. .NET 3.5 dodał metody rozszerzające, które obejmowały LINQ standard query operators
podobne Where
i First
, z dowolnymi operatorami, które wymagają predykatów lub przyjmowania funkcji anonimowych 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ń, zepsutą wersją metody (jeśli wolisz "w połowie skompilowaną"), która może zostać przeanalizowana przez dostawcę zapytania i odpowiednio użyta.
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
znajduje się metoda anonimowa ( Func<Person, bool>
), która może być wykonana jak każda inna metoda. Enumerable.Where
wykona metodę raz dla każdej osoby, yield
określając wartości, dla których metoda zwróciła true
.
W drugim bloku x => x.Age > 18
znajduje się drzewo wyrażenia ( Expression<Func<Person, bool>>
), które można traktować jako „właściwość„ Wiek ”> 18”.
Pozwala to na istnienie rzeczy takich jak LINQ-to-SQL, ponieważ mogą analizować drzewo wyrażeń i konwertować je na równoważny kod SQL. A ponieważ dostawca nie musi wykonywać, dopóki nie IQueryable
zostanie wyliczony (w końcu implementuje IEnumerable<T>
), może łączyć wiele operatorów zapytań (w powyższym przykładzie Where
i FirstOrDefault
), aby dokonywać mądrzejszych wyborów dotyczących sposobu wykonania całego zapytania względem danych bazowych źródło (jak używanie SELECT TOP 1
w SQL).
Widzieć: