Как вставить отдельный объект, который может уже существовать в базе данных с помощью NHibernate? - PullRequest
0 голосов
/ 19 ноября 2009

У меня есть следующий фрагмент кода:

using (var scope = DataAccessPortal.DataContext(DB.Main).OpenStatementScope())
using (var transaction = scope.BeginTransaction())
{
  // Several other database operations.
  if (scope.ExistsById(obj.GetType(), obj.Id))
  {
    scope.Update(obj);
  }
  else
  {
    scope.Insert(obj);
  }
  transaction.Commit();
}

Где scope и transaction - это тонкие абстрактные слои вокруг объектов сеанса и транзакции NHibernate соответственно, ExistsById сопоставляется с HQL-запросом, чтобы проверить, найден ли данный идентификатор в базе данных, Update и Insert сопоставление с соответствующими операциями сеанса.

Цель кода - обновить несколько объектов в базе данных, а затем обновить некоторый объект в базе данных, который может или не может быть там уже найден - код обновления или вставки.

Мне не нравится код обновления или вставки, потому что он дает два приема в базу данных. Можно ли выполнить одну и ту же задачу всего за одну поездку с помощью NHibernate?

Мои ограничения:

  • База данных поставляется без предопределенных хранимых процедур. Если NHibernate позволяет создавать один динамически независимым от БД способом, то хорошо (как ???), иначе использование хранимой процедуры не вариант.
  • Скорее всего, объект уже существует в базе данных, поэтому я мог бы просто выполнить обновление, поймать исключение, если объект не существует, и затем повторить попытку с помощью Insert. Однако код обновления или вставки является частью более крупной транзакции. Таким образом, его сбой также приводит к сбою транзакции, что означает, что мне придется повторить всю транзакцию, а не только фрагмент кода обновления или вставки. Я не уверен, что это предпочтительнее, чем сейчас.

1 Ответ

1 голос
/ 19 ноября 2009

Вам понадобится БД в обоих случаях. Сеанс NHibernate действует как клиентский кеш, который поддерживает синхронизацию бизнес-объекта и БД. Таким образом, если вы отсоединяете, а затем повторно присоединяете объект, у сеанса нет другого способа, кроме как перепроверять БД относительно объекта. Другого пути нет, если задуматься на секунду ...

Обычно это делается с помощью метода сессий Refresh (), подобного этому (псевдокод):

ISession session = GetSession(); 
session.Refresh(obj); 
session.DoSomething();

Неважно, есть ли у вас какой-то фасад или обертка вокруг. Общая схема остается прежней: вы должны проверить БД, прежде чем что-то делать ...

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