Проблема с операцией UPDATE в Entity Framework 4 (чистые POCO)
У меня есть модель Entity Framework 4.0, реализованная с использованием чистых POCO (без генерации кода, без самоконтроля сущностей, просто старые объекты CLR).
Теперь вот код, который у меня есть в моем пользовательском интерфейсе для выполнения ОБНОВЛЕНИЯ:
[HttpPost]
public ActionResult UpdatePerson(Person person)
{
repository.Attach(person);
unitOfWork.Commit();
}
По сути, у меня есть метод действия, который принимает строго типизированный объект Person, и мне нужно ОБНОВИТЬ эту сущность.
Не выдает ошибку, но и не сохраняет изменения в БД.:(
Когда я проверяю EntityState во время "коммитов" моей единицы работы:
var entities = ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
Я вижу свою сущность с EntityState.Unchanged.
Так что это объясняет, почему это не было сохранено. Мои операции поиска, добавления, удаления работают нормально (сохраняются правильно). Но ОБНОВЛЕНИЕ, кажется, не работает.
Я обнаружил, что некоторые потоки говорят, что мне нужно вручную установить состояние объекта:
ctx.ObjectStateManager.ChangeObjectState(person, EntityState.Modified);
Это верно? Куда бы я положил эту логику? Выставить как операцию на моей единице работы?
Очевидно, что проблема заключается в том, что у меня нет отслеживания изменений, из-за использования Pure POCO (без получения EntityObject, без реализации INotifyPropertyChanging).
Но я не нашел проблемы с этим до сих пор.
Что я делаю неправильно?
1 ответ
Ну, поскольку у вас нет отслеживания изменений и т. Д., У EF должен быть способ определить, что делать с присоединенным объектом, когда SaveChanges()
называется. По умолчанию EntityState не изменяется, поэтому, если вы хотите обновить, вы должны вручную установить состояние.
Другим способом было бы запросить Person
с этим идентификатором, перепишите свойства с данными, которые вы выбираете из контроллера, и вызовите SaveChanges()
, На самом деле это более безопасный способ, так как вы можете защитить себя от ситуации, когда Person удаляется, пока пользователь редактирует веб-форму; но это, очевидно, требует дополнительного обхода БД, что часто менее желательно.
В любом случае у меня был бы репозиторий Update()
метод (более конкретный, чем Attach
), что на самом деле прикрепит сущность и изменит EntityState
в Modified
, И у вас все еще есть относительно чистый код в вашем действии:
public ActionResult UpdatePerson(Person person)
{
repository.Update(person);
unitOfWork.Commit();
}