Wydajność Where - Cosmos DB, GetItemLinqQueryable, Func<T, bool> vs Expression<Func<T, bool>>

0

Natrafiłem na pytanie, na które odpowiedzi nie potrafię znaleźć na google. Microsoft.Azure.Cosmos.Container ma metodę GetItemLinqQueryable(), która umożliwia odpytywanie Cosmos DB za pomocą LINQ. Where() obecne w IOrderedTemplate<T> zwracanym przez GetItemLinqQueryable() ma dwie podstawowe wersje, jedna przyjmuje jako argument Func<T, bool>, druga Expression<Func<T, bool>>. O ile działanie drugiego overloada w miarę rozumiem, bo działa przy tłumaczeniu LINQ na "sql" tak samo, jak dzieje się to dla EF i SQL Server, o tyle pierwszy (przyjmujący Func<T, bool>) jest dla mnie zagadką.
Zdrowy rozsądek podpowiada mi, że żeby filtrować dane za pomocą metody po stronie C#, wszystkie dane muszą być ściągnięte i zadziała to jak linq-to-object, czyli najwolniejszy możliwy sposób przetwarzania danych z bazy.
Czy mam rację?

0

A nie jest tak, że Func kompilator domyślnie rzutuje do Expression? Expression służy temu, że mógłbyś zrobić np. predefiniowane zapytanie i złożyć lambdę ręcznie.
Co do zasady działania, framework bada Expression Tree i na jego podstawie buduję zapytanie do docelowej bazy.

1

Nie da się zrzutować ani przekonwertować Func na Expression, działają kompletnie inaczej. Acz zapewne da się Expression na Func.
EF przy kompilowaniu lambdy do sql poleci wyjątek, jeśli w expression użyjesz metody spoza dozwolonego setu (SqlFunctions i SqlFunctions2 bodajże), a to dlatego, że linq-to-sql rządzi się innymi, dużo bardziej restrykcyjnymi prawami niż linq-to-objects. Zresztą tak na logikę: jak sobie wyobrażasz przetłumaczenie na sql metody jakiegoś obiektu, która może używać innych metod innych obiektów, a wszystkie te obiekty mogą mieć jakiś stan i dalsze zależności?

0

Z konwersją mogłem faktycznie przekręcić, ale jak dziala Entity Framework? :) Wychodzisz np. od DbSet.Where, przekazujesz lambdy, framework przechodzi po Expression Tree i zmienia to na SQL.

1 użytkowników online, w tym zalogowanych: 0, gości: 1