我正在重写我的应用程序以使用实体框架。我感到困惑的是我写的代码看起来像是在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();
有没有办法最小化所有数据库调用?
答案 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中更容易实现这一点。