2012-07-05 27 views
3

我注意到在使用Find()方法時實體框架生成了一些效率低下的查詢。例如,這裏是我的C#代碼。實體框架在使用Find()時生成效率低下的選擇

Model model = unit.Repository.DbSet.Find(model.ID); 

生成查找()查詢

DECLARE @p0 int = 1 

SELECT 
[Limit1].[ID] AS [ID], 
[Limit1].[UserID] AS [UserID], 
[Limit1].[Started] AS [Started], 
[Limit1].[Updated] AS [Updated], 
[Limit1].[Completed] AS [Completed] 
FROM (SELECT TOP (2) 
     [Extent1].[ID] AS [ID], 
     [Extent1].[UserID] AS [UserID], 
     [Extent1].[Started] AS [Started], 
     [Extent1].[Updated] AS [Updated], 
     [Extent1].[Completed] AS [Completed] 
     FROM [dbo].[Table] AS [Extent1] 
     WHERE [Extent1].[ID] = @p0 
) AS [Limit1] 

這似乎是運行完全是另外一個選擇查詢,這是不必要的。以下是使用SingleOrDefault()方法的輸出。

生成的SingleOrDefault()查詢

DECLARE @p__linq__0 int = 1 

SELECT TOP (2) 
[Extent1].[ID] AS [ID], 
[Extent1].[UserID] AS [UserID], 
[Extent1].[Started] AS [Started], 
[Extent1].[Updated] AS [Updated], 
[Extent1].[Completed] AS [Completed] 
FROM [dbo].[Table] AS [Extent1] 
WHERE [Extent1].[ID] = @p__linq__0 

是有一個原因是Find()生成兩個選擇? 方法應該避免使用Find()方法嗎?

+2

您是如何評估查詢效率低下的? SQL服務器中的查詢執行引擎可能會優化它。 – 2012-07-05 15:36:58

+0

這個問題可以幫助:http://stackoverflow.com/questions/7822877/why-does-the-entity-frameworks-dbcontext-find-generate-a-query-with-select-to – ken2k 2012-07-05 15:47:56

+0

@LadislavMrnka我正在使用MiniProfiler的ASP MVC – 2012-07-05 17:20:20

回答

2

我懷疑這兩者之間有什麼性能差異,至少對於sql server來說。它看起來像第一個只是有一個額外的選擇包裝。在我生成完全相同的計劃的數據庫上運行一個類似的查詢,所以我會想象外層select在執行計劃中得到了優化。

+0

是的,你是對的。我只是擔心,當查詢變得更復雜(如包含多個導航屬性),它可能會減慢。 – 2012-07-05 17:19:09

+2

我對Entity框架本身並不太瞭解,但文檔說:「如果實體不在上下文中,那麼將執行查詢並根據數據源中的數據進行評估」。這對我來說意味着Find和SingleOrDefault之間的區別在於,如果FindO在SingleOrDefault總是碰到數據庫的上下文中,Find不會觸及數據庫。所以從性能方面來說,如果您已經在當前上下文中檢索過,Find可能會更快。 – 2012-07-05 19:52:04

+0

@Sbossb:'Find'永遠不會加載導航屬性。它只是尋找一條記錄。無論如何,EF會產生奇怪的查詢,但這是使用它的代價。要麼你喜歡它提供的抽象,你已經準備好支付成本,或者你可以接受書面查詢。 – 2012-07-05 20:45:21