2010-02-11 119 views
4

我有一個簡單的數據庫具有站點,並且每個站點都有一堆郵件。實體框架不發送Where子句作爲WHERE子句SQL Server

我試圖得到一定的站點(我有一個變量,名爲網站已經是EF帶來的一個實例)

第一個明顯的事情是所有「公共」的帖子:

var posts = from post in site.Posts 
       where post.Public == true 
       orderby post.PublicationTime descending 
       select post; 

這給我帶來了我想要的東西,但看着SQL Server Profiler,WHERE只是過濾Public字段,而不是過濾網站。實際上,在SQL Server中運行Profiler捕獲的查詢確實會將所有站點的所有帖子都帶回(這顯然是在稍後在ASP.Net端進行過濾)。

然後我嘗試:

var posts = from post in db.Posts 
       where post.Site == site && post.Public == true 
       orderby post.PublicationTime descending 
       select post; 

相同的結果。

我在這裏做一些根本上愚蠢的事情嗎?
Entity Framework總是在客戶端過濾嗎?

謝謝!
Daniel

+0

你能後的網站/帖子班? – 2010-02-11 02:52:15

+0

我假設Public是一個布爾值,但是Site是什麼類型? – 2010-02-11 02:53:51

+0

網站是一個模型實體,與帖子的關係,其中一個網站有很多帖子 – 2010-02-11 02:56:48

回答

7

您需要了解LINQ to Entities和LINQ to Objects之間的區別。在使用實體框架時跟蹤這一點非常重要。

當您針對ObjectContext發出查詢時,則您正在使用LINQ to Entities。這將返回一個IQueryable。只要您使用IQueryable類型的變量,您可以使用LINQ API進一步編寫查詢,並且當您最終枚舉結果時,它將轉換爲SQL。

但是你說:

(我有一個網站名爲變量已經是EF帶來的一個實例)

這裏您要查詢的對象的屬性,讓你的工作在LINQ to Objects中,而不是LINQ to Entities。這意味着您的查詢具有不同的提供者,並且不會轉換爲SQL。

關於你提到的第二個查詢:

var posts = from post in db.Posts 
      where post.Site == site && post.Public == true 
      orderby post.PublicationTime descending 
      select post; 

的EF不會讓你在L2E情況下做的同一性比較。您必須改爲比較密鑰。嘗試:

var posts = from post in db.Posts 
      where post.Site.Id == site.Id && post.Public 
      orderby post.PublicationTime descending 
      select post; 

BTW,我改變post.Public == truepost.Public。我認爲它更乾淨。如果你傳遞一個Func<TEntity,Boolean>.Where方法,過濾器的功能是從數據庫查詢返回後應用

3

如果任何人有這種使用方法的語法有問題。這是因爲.Where方法的返回值返回一個IEnumerable。另一方面,如果您將Expression<Func<TEntity,Boolean>傳遞給.Where方法,則篩選器函數會生成發送到數據庫的where子句。這是因爲.Where返回一個IQueryable。只要你堅持使用IQueryables,你就構建了發送到數據庫的查詢。當您返回一個IEnumerable時,使用該方法之前的所有內容創建查詢,並將IEnumerable之後的所有內容應用於返回的內容。如果您將lambda函數存儲在一個變量中,這才真正重要。如果您將lambda直接傳遞給.Where方法,則通常不會有問題。希望這可以幫助!!

的IEnumerable其中:https://msdn.microsoft.com/en-us/library/bb549418(v=vs.110).aspx

的IQueryable其中:https://msdn.microsoft.com/en-us/library/bb535040(v=vs.110).aspx