2009-10-02 58 views
11

我正在重寫我的應用程序以使用實體框架。我感到困惑的是我寫的代碼看起來像是在不必要地跳過sql服務器。例如,我有一個類似於SO的問題答案網站。當我添加一個問題的答案 - 這裏是我使用的代碼:爲什麼實體框架對數據庫做了很多往返操作?

var qu = context.question.where(c => c.questionID == 11).First(); //Database call here 
var answer = new answer(); 
answer.title = "title here"; 
answer.desc = "desc here"; 
answer.question = qu; 
context.SaveChanges(); //Database call here 

在上面的代碼中有2個數據庫調用權嗎?如果是這樣,爲什麼我不能直接添加一個問題的答案?如

var ans = answer.Createanswer (0, "title here", "desc here", questionID) 
context.SaveChanges(); 

有沒有辦法最小化所有的數據庫調用?

+1

問得好... –

回答

11

正如AlexJ的EF設計師http://blogs.msdn.com/alexj/archive/2009/06/19/tip-26-how-to-avoid-database-queries-using-stub-entities.aspx

而且這一切都落在領域的「優化」,這在不經常簡單,因爲它似乎

使用簡單的方法之一解釋,SQL將執行一個讀取操作來加載FK(問題)並緩存結果,然後在一個單獨的命令中執行一個應該使用緩存的FK結果的插入操作。使用附加的FK方法仍然會導致服務器爲FK執行讀取操作,這只是意味着一次往返SQL Server的次數減少。所以問題就變成了 - 隨着時間的推移,往返成本比增加的代碼複雜度更加昂貴?

如果應用程序和SQL Server在同一臺機器上這個開銷是非常小的

而且,如果FK是一個大的或寬表的聚簇索引的IO開銷可能顯著大於如果是在剛剛FK值一個單獨的標準指數 - 假設查詢優化器是:-)

-3

它可以完成,但在.NET 3.5中非常痛苦。他們在.NET 4.0中使這更容易。

8

您實際上不需要加載問題來設置關係。相反,您可以使用EntityReference

Answer.QuestionReference = new EntityReference<Question>(); 
Answer.QuestionReference.EntityKey 
    = new EntityKey("MyContextName.Question", "Id", questionId); 

我個人使用,用於設置實體按鍵

public static void SetEntityKey<T>(this EntityReference value, int id) 
{ 
    value.EntityKey = new EntityKey("ContextName." + typeof(T).Name, "Id", id); 
} 

因此,它應該是這樣的,而不是一個擴展方法。

Answer.QuestionReference = new EntityReference<Question>(); 
Answer.QuestionReference.SetEntityKey<Question>(questionId); 
+0

你不能用「這個的EntityReference 」正常工作,避免明確調用SetEntityKey什麼時候? – devio