Почему Entity Framework делает так много обходов базы данных? - PullRequest
11 голосов
/ 03 октября 2009

Я переписываю свое приложение, чтобы использовать платформу сущностей. Что меня смущает, так это то, что код, который я пишу, выглядит так, как будто он делает ненужные трипты на сервере 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();

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

Ответы [ 3 ]

11 голосов
/ 03 октября 2009

Как объяснил 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 является кластеризованным индексом для большой или широкой таблицы, накладные расходы ввода-вывода могут быть значительно больше, чем если бы это был отдельный стандартный индекс только для значения FK - при условии, что оптимизатор запросов работает правильно :-)

8 голосов
/ 03 октября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...