Как проверить нарушение уникального ограничения в nHibernate и DDD перед сохранением?

У меня есть объект модели Account и ограничение UNIQUE на Name счета. В Domain Driven Design, используя nHibernate, как мне проверить единственность имени перед вставкой или обновлением объекта?

Я не хочу полагаться на исключение nHibernate, чтобы поймать ошибку. Я бы хотел вернуть пользователю более красивое сообщение об ошибке, чем непонятное не удалось выполнить пакетную команду.[SQL: SQL недоступен]

В вопросе Где я должен разместить проверку уникальности в DDD?, кто-то предложил использовать Спецификацию, например, так.

Account accountA = _accountRepository.Get(123);
Account accountB = _accountRepository.Get(456);
accountA.Name = accountB.Name;

ISpecification spec = new Domain.Specifications.UniqueNameSpecification(_accountRepository);
if (spec.IsSatisfiedBy(accountObjA) == false) {
   throw new Domain.UnicityException("A duplicate Account name was found");
}

с кодом Спецификации как:

public bool IsSatisfiedBy(Account obj)
{
   Account other = _accountRepository.GetAccountByName(obj.Name);
   return (other == null);
}

Это работает при вставке, но не при обновлении. Я попробовал изменить код на:

public bool IsSatisfiedBy(Account obj)
{
   Account other = _accountRepository.GetAccountByName(obj.Name);

   if (obj == null) {  // nothing in DB
      return true;
   }
   else {              // must be the same object.
      return other.Equals(obj);
   }
}

Проблема в том, что nHibernate выпустит обновление базы данных, когда выполнит GetAccountByName(), чтобы восстановить возможный дубликат...

return session.QueryOver().Where(x => x.Name == accntName).SingleOrDefault();

Итак, что мне делать? Является ли спецификация не правильным способом сделать это?

Спасибо за ваши мысли!

8
задан Community 23 May 2017 в 12:31
поделиться