dst*_*stj 8 nhibernate domain-driven-design
我在帐户的名称上有一个帐户模型对象和一个UNIQUE约束.在域驱动设计中,使用nHibernate,在插入或更新实体之前,如何检查名称的unicity ?
我不想依赖于nHibernate异常来捕获错误.我想向我的用户返回一个更漂亮的错误消息而不是模糊could not execute batch command.[SQL: SQL not available]
在问题我应该在哪里进行DDD的独特检查?有人建议使用这样的规格.
Account accountA = _accountRepository.Get(123);
Account accountB = _accountRepository.Get(456);
accountA.Name = accountB.Name;
ISpecification<Account> spec = new Domain.Specifications.UniqueNameSpecification(_accountRepository);
if (spec.IsSatisfiedBy(accountObjA) == false) {
throw new Domain.UnicityException("A duplicate Account name was found");
}
Run Code Online (Sandbox Code Playgroud)
使用规范代码:
public bool IsSatisfiedBy(Account obj)
{
Account other = _accountRepository.GetAccountByName(obj.Name);
return (other == null);
}
Run Code Online (Sandbox Code Playgroud)
这适用于插入,但不适用于执行更新,因为.我尝试将代码更改为:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是nHibernate在执行时会GetAccountByName()向数据库发出更新以恢复可能的重复...
return session.QueryOver<Account>().Where(x => x.Name == accntName).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
所以我该怎么做?规范不是正确的方法吗?
谢谢你的想法!
小智 5
我不喜欢数据访问的规范模式,它似乎总是跳起来完成任何事情.
但是,你的建议,实际上归结为:
......几乎是完成任务的最简单方法.
如果您的数据库及其.NET客户端正常传播侵犯唯一约束的表和列,则依赖于数据库异常是另一种方法.我相信大多数司机都没有这样做(??),因为他们只是抛出一个ConstraintException说法"在表格ABC上违反了约束XYZ".你当然可以在你的唯一约束命名上有一个约定来说出类似于UK_MyTable_MyColumn的东西,并使用字符串魔法来拉出表和列名.
NHibernate有一个ISQLExceptionConverter你可以Configuration在设置NHibernate时插入对象的东西.在此内容中,您将接触到.NET数据客户端的异常.您可以使用该异常来提取表和列(可能使用约束名称?)并使用用户友好消息抛出一个新的Exception.
使用数据库异常方式更具性能,您可以将大量检测唯一约束违规代码推送到基础架构层,而不是逐个处理每个代码.
使用query-first-then-add方法值得指出的另一件事是,为了完全事务安全,您需要将事务级别升级为可序列化(这使得最差的并发性)完全是防弹的.您是否需要完全防弹,取决于您的应用需求.
| 归档时间: |
|
| 查看次数: |
2955 次 |
| 最近记录: |