为什么实体框架会向数据库进行如此多的往返?

时间:2009-10-02 22:43:00

标签: c# asp.net-mvc entity-framework linq-to-entities

我正在重写我的应用程序以使用实体框架。我感到困惑的是我写的代码看起来像是在sql server上做了不必要的三脚架。例如,我有一个类似于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();

有没有办法最小化所有数据库调用?

3 个答案:

答案 0 :(得分:11)

正如AlexJ设计师之一[{3}}

所解释的那样

此外,这一切都属于“优化”领域,而这种优化往往不像看起来那么简单

使用简单的方法,SQL将执行读取操作以加载FK(问题)并缓存结果,然后在单独的命令上执行应该使用缓存的FK结果的插入操作

使用附加的FK方法仍会导致服务器对FK执行读取操作,这意味着只需少一次往返SQL Server。所以问题就变成了 - 随着时间的推移,往返往往比增加的代码复杂性更昂贵?

如果应用程序和SQL Server在同一台机器上,则此开销非常小

此外,如果FK是大型或宽型表上的聚簇索引,则IO开销可能远远超过仅仅是FK值的单独标准索引 - 假设查询优化器工作正常:-)

答案 1 :(得分:8)

您实际上不需要加载问题来设置关系。相反,您可以使用EntityReference

e.g。

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); 

答案 2 :(得分:-3)

可以这样做,但在.NET 3.5中却非常痛苦。他们在.NET 4.0中更容易实现这一点。