假設我有一個IQueryable<T>
表達式,我想要封裝定義,將其存儲並重用,或稍後將其嵌入到更大的查詢中。例如:如何維護LINQ延遲執行?
IQueryable<Foo> myQuery =
from foo in blah.Foos
where foo.Bar == bar
select foo;
現在我相信我可以保留myQuery對象並像我描述的那樣使用它。但有些事情我不確定:
如何最好地參數化它?最初我已經在方法中定義了這個,然後返回
IQueryable<T>
作爲該方法的結果。這樣我可以將blah
和bar
定義爲方法參數,我想它只是每次創建一個新的IQueryable<T>
。這是封裝IQueryable<T>
邏輯的最佳方式嗎?有其他方法嗎?如果我的查詢解析爲標量而不是
IQueryable
會怎麼樣?例如,如果我想要這個查詢完全如圖所示,但是追加.Any()
只是讓我知道是否有匹配的結果?如果我添加(...).Any()
那麼結果是bool
並立即執行,對吧?有沒有辦法利用這些Queryable
運營商(Any
,SindleOrDefault
等)沒有立即執行? LINQ到SQL如何處理這個問題?
編輯:第2部分是真的更多的想了解什麼是IQueryable<T>.Where(Expression<Func<T, bool>>)
與IQueryable<T>.Any(Expression<Func<T, bool>>)
之間的限制不同。看起來好像後者在執行被延遲時創建更大的查詢時不那麼靈活。可以附加Where()
,然後可以添加其他結構,最後執行。由於Any()
返回一個標量值,因此它聽起來像在構建查詢的其餘部分之前它會立即執行。
這聽起來像在#1,具有一個新的'IQueryable'每次基本構造的方法是*好事*,因爲這樣我就不會遇到與處置問題。在#2中,我很困惑LINQ-to-SQL如何翻譯「Any」運算符,但我不能推遲。如果我在較大的查詢中使用「Any」運算符,那麼它會立即在那裏執行,或者它是否是較大查詢執行的一部分? – mckamey 2009-08-20 19:16:05
好吧,我想我快到了。如果我將'.Any()'嵌入到'where'子句中,那麼它將不會在循環中執行它,對嗎?它會編譯爲適當的SQL表達式並將其發送。所以實際上,它不是'.Any()',它可以防止延遲執行,因爲它是如何被使用的。基本上,如果* whole *查詢的結果是標量,那麼編譯器會計算出您現在需要的結果,而不是繼續構建'IQueryable'。 –
mckamey
2009-08-21 15:13:41
@McKAMEY正確,只要你在不延遲的上下文中使用.Any(),那麼它將執行。在.Where()的情況下,它正在尋找一個可推遲的表達式,所以你沒事。在var或foreach循環的情況下,這些會導致執行,因爲它們不是可延遲的。 – Joseph 2009-08-21 15:42:33