Сценарии и проблемы
1) Про AsNoTracking, Attach и ошибку "The instance of entity type cannot be tracked because another instance with the same key value for {'key'} is already being tracked..."
Вводные:
Делаем следующую выборку из 2 таблиц
Entity1 -> LinkedEntity1
Entity2 -> LinkedEntity1
Где Entity1, Entity2 - две строки из таблицы Entity, а LinkedEntity1 - одна строка из связанной таблицы. (Обе сущности Entity[i] ссылаются на одну и ту же строку - LinkedEntity1)
Change Tracking | Отслеживание изменений
- Когда включен AsNoTracking
ReferenceEquals(Entity1.LinkedEntity, Entity2.LinkedEntity) - false
Т.е. фреймворк не только не отслеживает данные, но и не фиксирует повторяющиеся сущности из БД. Итого создано 2 экземпляра LinkedEntity. - Когда выключен AsNoTracking
ReferenceEquals(Entity1.LinkedEntity, Entity2.LinkedEntity) - true
Фреймворк обнаружил повторяющуюся сущность и создал только 1 экземпляр LinkedEntity.
Завершение:
В случае, если попытаться прикрепить полученный графы (Entity1 и Entity2) объектов к другому контексту, то можно получить ошибку из-за двух экземпляров LinkedEntity с одинаковым первичным ключом.
Поэтому необходимо сделать выборку с включенным трекингом, даже если мы не планируем менять данные в том-же контексте, а планируем присоединить их к другому.
2) Уровни изоляции и Табличные указания (Хинты)
Варианты на основе механизма Interception EF | Перехватчики.
Entity Framework with NOLOCK
https://stackoverflow.com/questions/926656/entity-framework-with-nolock
How to implement Select For Update in EF Core
https://stackoverflow.com/questions/37984312/how-to-implement-select-for-update-in-ef-core
3) Использование конструктора типа
1) По умолчанию фреймворк будет использовать конструктор без параметров, чтобы фреймворк попытался выбрать подходящий конструктор, конструктора без параметров быть не должно. (При этом достаточно создать конструктор с необязательным параметром)
2) В качестве параметров конструктора нельзя передавать навигационные свойства, а также комплексные/вложенные свойства.
4) Изменение сущности без загрузки из БД.
Тип | Описание | Материалы |
---|---|---|
Обычное свойство. Навигационное свойство. | Достаточно просто выполнить Attach объекта. Могут возникнуть проблемы при попытке присвоить свойству значение по умолчанию. item.NavigationId = null; //Явно помечаем свойство, как измененное. entry.Property(e => e.NavigationId).IsModified = true; | how to update entity without first loading it Update doesn't set foreign key to null when changed outside of context #6244 |
Навигационное свойство для подчиненного объекта. |
|
Change Tracking | Отслеживание изменений
Дополнение: рассматривается сценарий с отслеживанием изменений по умолчанию (с использованием автоматического определения изменений через сравнение, а не IPropertyChanged)
5)
Setting the On Update Cascade Constraint with Entity Framework Core
https://stackoverflow.com/questions/51641145/setting-the-on-update-cascade-constraint-with-entity-framework-core