Почему удаление объектов из сеанса не фиксирует изменения в базе данных? - PullRequest
2 голосов
/ 16 февраля 2012

Я использую NHibernate в моем приложении и имею следующую ситуацию.(Обратите внимание, что здесь ситуация гораздо проще для понимания)

Объект запрашивается из базы данных.Он редактируется и обновляется с использованием Session.Update().Затем объект выселяется из сеанса (используя Session.Evict(obj)) до совершения транзакции.Ожидаемый результат состоит в том, что изменения сохраняются в базе данных.

Это нормально работало, когда у меня был столбец Id в качестве столбца NHibernate identity.Недавно мы изменили столбец Id, чтобы он не был идентифицирован.В результате вышеприведенный сценарий не сохраняется в базе данных, если я не позвоню явно Session.Flush() до того, как выселю.

Может ли кто-нибудь указать / объяснить мне причину такого поведения?

Эта ссылка, NHibernate Session.Flush & Evict vs Clear , упоминает кое-что о Evict и столбце идентификации, что для меня не очень понятно.

Ответы [ 2 ]

9 голосов
/ 16 февраля 2012

Ваш рабочий процесс не верный.

Во-первых, когда вы извлекаете объект из базы данных, session.Update(entity) ничего не делает. Изменения произойдут автоматически на Flush/Commit

Далее Evict удаляет все знания об объекте, которые есть в сеансе, поэтому он не сохранит никаких изменений, примененных к нему. Вы почти никогда не должны использовать этот метод в нормальных условиях, что заставляет меня думать, что вы неправильно обрабатываете сеанс.

В-третьих, тот факт, что использование identity заставляет вставки немедленно произойти на Save, является ограничением, а не функцией.

Правильный рабочий процесс:

using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    var entity = session.Get<EntityType>(id);
    entity.SomeProperty = newValue;
    transaction.Commit();
}

Структура точная (операторы using и т. Д.) Может измениться в настольном приложении, но основная идея та же.

2 голосов
/ 16 февраля 2012

Удостоверение заставляет NHibernate немедленно сохранить сущность в базе данных на session.Save() Неидентификация позволяет пакетировать вставки для отправки их в целом.Evict удалит всю информацию об объекте из сеанса.Поэтому, имея идентификатор, он забывает об объекте, который уже находится в базе данных, даже если сеанс не знает.

, чтобы исправить это, можно

  • установить Flushmode.Auto (вызывает немедленную очистку)
  • вызов session.Flush() до Evict
  • Выселение после завершения транзакции

, что является наилучшим вариантом, зависит от контекста

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...