EF 4.1 Поиск идей о том, как ускорить добавление строк - PullRequest
0 голосов
/ 07 марта 2012

Я заполняю свою базу данных из онлайн-данных, используя цикл вроде (упрощенный, без проверки ошибок):

foreach (var catalog in catalogs)
{
   var result = Items(catalog, state, context);
   while (result != null)
   {
      result.ForEach(r => context.DbContext.Items.Add(r));
      context.DbContext.SaveChanges();
      result = Items(catalog, state, context);
   }
}                  

Коду требуется некоторое время, чтобы получить XML-ответ от сервера и декодировать его в XElement, используя XElement.Load в потоке ответов. Он декодируется в список элементов, который содержит максимум 50 элементов - это то, что я запрашивал с сервера на каждом проходе цикла. Этот чанк сразу же сохраняется в таблице из-за вызова SaveChanges.

8/10 времени цикла тратится либо на добавление элементов в DbContext, либо на вызов SaveChanges, либо на оба. Связь с удаленным сервером и декодирование ответного XML в список объектов составляют 2/10.

Как повысить эффективность хранения данных в базе данных, оставаясь при этом в EF?

Я знаю, что могу выполнить массовую загрузку базы данных из XML, но это заставит меня выяснить, какие SQL-операторы мне нужно написать, потому что несколько связанных таблиц обновляются с помощью вызова SaveChanges выше, и поэтому я начинаю терять Преимущества использования EF.

1 Ответ

2 голосов
/ 07 марта 2012

Вкратце: вы не можете ускорить процесс вставки с помощью чистого EF, потому что EF имеет очень низкую производительность для массовой / пакетной обработки данных . У вас две проблемы:

  • Добавление объекта в контекст сопряжено с некоторыми затратами, и эта стоимость увеличивается с каждым объектом, уже присутствующим в контексте. Чтобы избежать этого, вы можете попытаться вызывать SavaChanges после каждого вызова на Add или даже пытаться использовать новый контекст для каждого пакета или даже каждый вызов Add.
  • EF создает отдельную базу данных для каждой записи, которую вы хотите вставить, обновить или удалить, поэтому обычно не имеет значения, как часто вы звоните SaveChanges. Избежать этого в основном можно только при использовании прямого SQL и создании одного SqlCommand, одновременно выполняющего все вставки.

Если вы хотите повысить производительность, используйте прямой SQL.

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