Почему инфраструктура Entity делает так много обращений к базе данных?

Я переписываю свое приложение для использования структуры сущности. Меня смущает код, который я пишу, похоже, что он делает ненужные отключения сервера 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

В приведенном выше коде есть два запроса на базу данных? Если да, почему я не могу добавить ответ на вопрос напрямую? таких как

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

Есть ли способ минимизировать все вызовы базы данных?

Ответ 1

Как объяснил 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 - при условии, что оптимизатор запросов работает правильно:-)

Ответ 2

На самом деле вам не нужно загружать вопрос, чтобы установить отношение. Вместо этого вы можете просто использовать 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); 

Ответ 3

Это можно сделать, но это очень больно в .NET 3.5. Они сделали это намного проще в .NET 4.0.