Автоматическое обнаружение изменений
При использовании большинства сущностей 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. Эти методы автоматически обнаруживают изменения только один раз после завершения операций добавления или удаления.