У меня есть следующий фрагмент кода:
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. Однако код обновления или вставки является частью более крупной транзакции. Таким образом, его сбой также приводит к сбою транзакции, что означает, что мне придется повторить всю транзакцию, а не только фрагмент кода обновления или вставки. Я не уверен, что это предпочтительнее, чем сейчас.