Różnica miedzy IEnumarable a IQueryable (LINQ to SQL)

Interfejsy IEnumerable oraz IQueryable mogą wydawać się bardzo podobne. W końcu IQueryable implementuje IEnumerable więc funkcjonalność musi być podobna. W praktyce poniższe dwa zapytania bardzo się różnią:

IEnumerable<Customer> customers = context.Customers.Where(c => c.FirstName.StartsWith("J"));
customers = customers.Take<Customers>(5);

IQueryable<Customer> customers = context.Customers.Where(c => c.FirstName.StartsWith("J"));
customers = customers.Take<Customers>(5);

Pierwsze zapytanie jest skrajnie niewydajne. Najpierw zostaną wybrani wszyscy klienci z imieniem zaczynającym się od litery J a dopiero potem lokalnie zostanie zwróconych pierwszych 5 wierszy. Jeśli zatem tabela zawiera milion wierszy to wszystkie  te wiersze zostaną odczytane z bazy danych. W SQL wyglądałoby to następująco:

select * from Customers WHERE FirstName like 'j%';

W pamięci powstanie tablica zawierająca milion elementów. Następnie metoda Take zwróci pierwszych 5 elementów.

W przypadku interfejsu IQueryable zapytanie wygląda juz w pełni optymalnie tzn:

select top(5) * from Customers WHERE FirstName like 'j%';

Należy zwrócić uwagę na top(5) – z bazy danych zostaną odczytane wyłącznie te wiersze, które tak naprawdę chcemy. Z przykładów widać, że bardzo łatwo napisać niewydajny kod. Wszelkie wywołania IEnumerable są wykonywane lokalnie i nie zostaną przetworzone bezpośrednio w zapytanie SQL.

5 thoughts on “Różnica miedzy IEnumarable a IQueryable (LINQ to SQL)”

Leave a Reply

Your email address will not be published.