Трекер изменений EF Core
Вопрос
Расскажите, как работает отслеживание изменений в EF Core и как оно влияет на производительность.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Состояния: Added, Unchanged, Modified, Deleted, Detached
Снимки исходных значений и DetectChanges при SaveChanges
Identity resolution: одна сущность на ключ в контексте
AsNoTracking и AsNoTrackingWithIdentityResolution для чтения
Долгоживущий контекст разрастается, DetectChanges замедляется
Attach и Update для отсоединённых сущностей и их опасности
Что могут спросить следом
- Что сделает Update для графа с новыми и старыми сущностями?
- Когда нужен ChangeTracker.Clear?
Разбор
Каждая загруженная через отслеживающий запрос сущность регистрируется в ChangeTracker со состоянием Unchanged, и для неё сохраняется снимок исходных значений. При SaveChanges вызывается DetectChanges: текущие значения сравниваются со снимками, изменённые свойства помечаются, и генерируются только нужные UPDATE с изменёнными колонками.
Ещё трекер обеспечивает identity resolution: в одном контексте для одного первичного ключа существует один объект. Если загрузить строку дважды, придёт тот же экземпляр.
Цена: память на снимки и время на DetectChanges, которое растёт с числом сущностей в контексте. Поэтому для чтения использую AsNoTracking, контексты держу короткими, а в пакетной обработке периодически вызываю ChangeTracker.Clear(). Для отсоединённых сущностей из API аккуратно использую Update: он помечает весь граф как изменённый и обновит все колонки, иногда лучше загрузить сущность и применить изменения.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.