Присоединение отключенного объекта к сеансу NHibernate; лучшая практика?
Мой репозиторий работает в модели UnitOfWork
; все операции, будь то поиск или сохранение, должны выполняться в рамках объекта токена IDisposable
UnitOfWork
, который за кулисами связан с Session
, который выполняет запрошенную работу. Итак, основной шаблон:
using (var uow = repo.BeginUnitOfWork())
{
try
{
//DB operations here; all repo methods require passing in uow.
...
repo.CommitUnitOfWork(uow);
}
catch(Exception)
{
repo.RollbackUnitOfWork(uow);
throw;
}
}
Я также применил некоторые методы-обертки, которые позволяют вам указывать лямбда или делегат, которые будут выполняться в этой структуре, избавляя от необходимости выполнять все эти строительные леса каждый раз.
Проблема заключается в том, что с использованием этой модели код должен "знать", что нужно пользователю, и загружать его с помощью NHUtil.Initialize()
в пределах UnitOfWork
. Когда UOW находится в конце используемого блока, сеанс, связанный с любым PersistentBags
, закрывается, и поэтому их невозможно оценить. Поскольку нетерминальная загрузка все впереди не всегда выполнима, а вид поражений - цель ORM с ленивой загрузкой, я реализую метод Attach()
.
Здесь вопрос; В отсутствие встроенного метода ISession.Attach()
существует три метода, которые я видел, чтобы связать объект с новым сеансом. Какая из них - лучшая практика для выполнения работы?
А:
if(!Session.Contains(domainObject))
Session.Update(domainObject);
В:
Session.Merge(domainObject);
С
Session.Lock(domainObject, LockMode.None);
Ответы
Ответ 1
D: Ничего из вышеперечисленного. Эффективное отключение ленивой загрузки, если ваш UOW слишком короткий и побеждает цель ленивой ORM. Тот факт, что вы должны повторно ассоциировать отключенные объекты как обычные операции, означает, что ваша единица рабочих границ неверна.
Слияние, обновление и блокировка имеют разные цели. Если вы застряли в своей текущей архитектуре, то Lock, вероятно, вы хотите.
- Обновление - связывает измененный объект
- Lock - связывает неизменный объект
- Объединить - если объект существует в
текущей сессии, то он обновляется
с изменениями от объединенного объекта,
в противном случае он будет таким же, как Lock