#asp.net-mvc #asp.net-mvc-3 #nhibernate
#asp.net-mvc #asp.net-mvc-3 #nhibernate
Вопрос:
У меня есть приложение MVC, использующее NHibernate для сохранения данных, но по какой-то причине, несмотря на удаление моего объекта из сеанса, он все еще сохраняется в базе данных.
У меня есть сложный объект, к которому я разрешаю пользователю применить изменение и заставить его пересчитать дочерние коллекции на основе нового значения свойства родительского объекта. Но я не хочу, чтобы эти изменения сохранялись, потому что я передаю полученные изменения обратно в представление для отображения только в качестве предварительного просмотра. Пользователь может зафиксировать их, но с помощью другого действия.
Сразу после того, как я запрашиваю NHibernate для своего объекта в этом процессе, я удаляю его из сеанса, но по какой-то причине он все еще сохраняется.
Согласно профилировщику NHibernate, похоже, это связано с фиксацией транзакции, которую я имею в фильтре, украшающем действие моего контроллера. Это было сделано из-за рекомендации, которую я прочитал относительно того, что элементы, прочитанные из базы данных, не кэшируются в кэш 2-го уровня, если транзакция не зафиксирована, даже если не было внесено никаких изменений. Даже в этом случае это не объясняет, почему фиксация приведет к тому, что у удаляемого объекта сохранятся изменения в базе данных. Я предполагаю, что мне не хватает чего-то, что объяснит это поведение, но я не уверен, чего?
Ответ №1:
Прав ли я в том, что вы запрашиваете объект, затем удаляете его из сеанса и вносите изменения для предварительного просмотра пользователем?
Вы также меняете дочерние коллекции? Потому что, насколько я помню, при удалении объекта из NH он автоматически не удаляет связанные дочерние объекты (по крайней мере, в NH версии v2.x).
Итак, когда вы изменяете какой-либо дочерний объект (и вы явно не удалили его), он пытается сохранить его и из-за некоторых каскадных правил пытается сохранить и родительский объект.
Комментарии:
1. Я начинаю задумываться о выселении вообще на самом деле. Чем больше я ищу, тем больше ссылок я нахожу, говорящих о том, что Evict() просто удаляет элемент из кэша первого уровня. Но очень мало упоминаний о том, что он отсоединен от сеанса. Я хотел бы иметь возможность щелкнуть переключателем и сделать объект в памяти временным, а не постоянным.
2. Я сам не использовал Evict(). На самом деле я пытался использовать его, но отказался по причинам, которые я упомянул. Я просто выполняю откат, когда не хочу сохранять объекты (например. при сбое проверки перед сохранением).