У меня есть объект модели 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();
Итак, что мне делать? Является ли спецификация не правильным способом сделать это?
Спасибо за ваши мысли!