我正在重写我的应用程序以使用实体框架。我感到困惑的是我写的代码看起来像是在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();
有没有办法最小化所有数据库调用?
正如EFJ设计师AlexJ所解释的那样 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值上的单独标准索引 - 假设查询优化器工作正常:-)
您实际上不需要加载问题来设置关系。相反,您可以使用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);
它可以完成,但在.NET 3.5中非常痛苦。他们在.NET 4.0中更容易实现这一点。