Автоматическое обнаружение изменений

При использовании большинства сущностей POCO определение того, как сущность изменилась (и поэтому какие обновления необходимо отправить в базу данных) обрабатывается алгоритмом обнаружения изменений. Обнаружение изменений работает путем обнаружения различий между текущими значениями свойств сущности и исходными значениями свойств, хранящимися в моментальном снимке при запросе или присоединении сущности. Методы, представленные в этом разделе, также применимы к моделям, созданным с помощью Code First и конструктора EF.

По умолчанию Entity Framework автоматически выполняет обнаружение изменений при вызове следующих методов:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Add
  • DbSet.AddRange
  • DbSet.Remove
  • DbSet.RemoveRange
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Отключение автоматического обнаружения изменений

Если вы отслеживаете много сущностей в контексте и вызываете один из этих методов много раз в цикле, то вы можете получить значительные улучшения производительности, отключив обнаружение изменений в течение цикла. Например:

using (var context = new BloggingContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;

        // Make many calls in a loop
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}

Не забудьте повторно включить обнаружение изменений после цикла. Мы использовали попытку или, наконец, чтобы убедиться, что он всегда повторно включен, даже если код в цикле создает исключение.

Альтернативой отключению и повторному включению является отключение автоматического обнаружения изменений в любое время и контекст вызова. ChangeTracker.DetectChanges явно или старательно используйте прокси-серверы отслеживания изменений. Оба этих варианта являются расширенными и могут легко вводить тонкие ошибки в приложение, поэтому используйте их с осторожностью.

Если необходимо добавить или удалить множество объектов из контекста, рассмотрите возможность использования DbSet.AddRange и DbSet.RemoveRange. Эти методы автоматически обнаруживают изменения только один раз после завершения операций добавления или удаления.