Улучшение производительности инициализации DbSet в Seed? - PullRequest
0 голосов
/ 25 февраля 2012

Я использую AutoMapper для отображения объектов из устаревшей базы данных в новую базу данных, объявленную сначала в коде EF:

  StartTimer("Map Customers");      
      var mfpCustomers = Mapper.Map<IEnumerable<LegacyDataModel.Customer>, IEnumerable<Customer>>(
        legacyEntities.Customers.Include(p => p.Demographics).ToList());
      StopAndPrintTimer("Map Customers");

      StartTimer("Iterate Customers");
      foreach (var p in mfpCustomers)
      {
        db.Customers.Add(p);       
      }
      StopAndPrintTimer("Iterate Customers");

Для каждого это то, что занимает больше всего времени. Я хотел бы отобразить непосредственно на DbSet(db.Customer), вместо того, чтобы делать foreach поверх db.Customers.Add(p);. Я не понял, как это сделать, поскольку нет ничего лучше, чем метод AddRange, разработанный специально для добавления большого количества объектов. Я знаю, как выполнять эти типы преобразований с помощью методов, основанных на множестве, в SQL, но это бессмысленная типизация, потому что intellisense не очень хорошо работает в этих сценариях в SSMS.

Этот код не обязательно должен быть очень быстрым, но необходимость ждать целую минуту каждый раз, когда я запускаю базу данных, усложняет разработку (и его нужно часто повторять из-за быстрой разработки новой базы данных). Также обратите внимание, что, поскольку это начальный метод, я не возражаю против полной замены существующих клиентов (поскольку их нет). Поэтому он не должен вести себя как AddRange в этом отношении, так как на самом деле я просто создаю новую коллекцию.

Любые идеи о том, как я могу улучшить производительность здесь? Любые идеи о том, как я могу отобразить всю коллекцию непосредственно в DbSet, не делая foreach для каждого экземпляра?

1 Ответ

1 голос
/ 27 февраля 2012

Каждый раз, когда вы вызываете db.Customers.Add (p), EF выполняет вызов DetectChanges, чтобы узнать, изменилось ли что-либо в вашем графе сущностей. Это помогает заставить все работать как положено, когда Add вызывается после внесения изменений в другие объекты. Однако DetectChanges может работать медленно, если в контексте много сущностей - у него есть O (n) время на количество сущностей. Так что в подобных случаях это может иметь большое значение, если вы временно отключите эти автоматические вызовы DetectChanges. Например:

try
{
    context.Configuration.AutoDetectChangesEnabled = false;

    foreach (var p in mfpCustomers)  
    {  
        db.Customers.Add(p);         
    }  
}
finally
{
    context.Configuration.AutoDetectChangesEnabled = true;
}

Более подробную информацию вы можете найти здесь: http://blogs.msdn.com/b/adonet/archive/2011/02/06/using-dbcontext-in-ef-feature-ctp5-part-12-automatically-detecting-changes.aspx

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