IEnumerable<T>reprezentuje kursor tylko do przodu T. .NET 3.5 dodał metody rozszerzające, które obejmowały LINQ standard query operatorspodobne Wherei 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 > 18znajduje się metoda anonimowa ( Func<Person, bool>), która może być wykonana jak każda inna metoda. Enumerable.Wherewykona metodę raz dla każdej osoby, yieldokreślając wartości, dla których metoda zwróciła true.
W drugim bloku x => x.Age > 18znajduje 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 IQueryablezostanie wyliczony (w końcu implementuje IEnumerable<T>), może łączyć wiele operatorów zapytań (w powyższym przykładzie Wherei 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 1w SQL).
Widzieć: