Załóżmy, że mam wyrażenie IQueryable<T>
, że chciałbym hermetyzować definicję, przechowywania i ponownego użycia lub osadzić go w większe zapytanie później. Na przykład:Jak utrzymać odłożoną realizację LINQ?
IQueryable<Foo> myQuery =
from foo in blah.Foos
where foo.Bar == bar
select foo;
Teraz wierzę, że mogę po prostu zatrzymać obiekt myQuery i używać go tak, jak to opisałem. Ale niektóre rzeczy nie jestem pewien o:
Jak najlepiej go parametryzacji? Początkowo zdefiniowałem to w metodzie, a następnie zwróciłem
IQueryable<T>
jako wynik tej metody. W ten sposób mogę zdefiniowaćblah
ibar
jako argumenty metody i myślę, że po prostu tworzy noweIQueryable<T>
za każdym razem. Czy jest to najlepszy sposób na zamknięcie logiki zIQueryable<T>
? Czy są inne sposoby?Co się stanie, jeśli moje zapytanie zostanie przetworzone na skalar, a nie na
IQueryable
? Na przykład, jeśli chcę, aby to zapytanie było dokładnie takie, jak pokazano, ale dołącz.Any()
, aby dać mi znać, czy są jakieś wyniki, które pasują do siebie? Jeśli dodaję(...).Any()
, wynikiem jestbool
i natychmiast wykonywane, prawda? Czy istnieje sposób na wykorzystanie tych operatorówQueryable
(Any
,SindleOrDefault
itp.) Bez natychmiastowego wykonania? W jaki sposób LINQ-SQL to obsługuje?
Edit: Część 2 jest naprawdę więcej o starając się zrozumieć, jakie są różnice między IQueryable<T>.Where(Expression<Func<T, bool>>)
ograniczenia vs. IQueryable<T>.Any(Expression<Func<T, bool>>)
. Wydaje się, że ta ostatnia nie jest tak elastyczna przy tworzeniu większych zapytań, w których wykonanie ma być opóźnione. Where()
można dołączyć, a następnie inne konstrukcje mogą być później dołączane, a następnie ostatecznie wykonane. Ponieważ Any()
zwraca wartość skalarną, wydaje się, że zostanie ona natychmiast wykonana, zanim będzie można zbudować pozostałą część zapytania.
To brzmi jak w # 1, ponieważ metoda, która w zasadzie tworzy nowe 'IQueryable' za każdym razem jest * dobrą rzeczą *, ponieważ w ten sposób nie napotkasz problemów ze zbieraniem. W # 2, jestem zdezorientowany, jak LINQ-SQL może tłumaczyć operatora Any, ale nie mogę odroczyć. Jeśli miałbym użyć operatora Any w większym zapytaniu, czy został on tam natychmiastowo wykonany, czy jest to część większego wykonania zapytania? – mckamey
OK Myślę, że już prawie jestem. Gdybym miał osadzić '.Any()' w klauzuli 'where', to nie wykonałoby tego w pętli, prawda? Kompiluje się do odpowiedniego wyrażenia SQL i wyśle je w dół. W efekcie nie jest to '.Any()', który zapobiega odroczeniu wykonania, ponieważ jest to w jaki sposób jest używany. Zasadniczo, jeśli wynik kwerendy * całkowitej * jest skalarem, wówczas kompilator podaje wynik, a nie kontynuuje budowania 'IQueryable'. –
mckamey
@McKAMEY poprawne, jak tylko użyjesz. Any() w kontekście, który nie zostanie odroczony, to zostanie wykonany. W przypadku .Where() szuka wyrażenia, które jest odraczane, więc wszystko w porządku. W przypadku var lub pętli foreach te przyczyny powodują, że nie są one odłożone. – Joseph