我有一个服务对象,负责一些业务逻辑验证。在对Update进行更新之前,它所做的是检查它所使用的实体是否符合某些业务规则。
必须检查的其中一条规则是,与数据库中的实体相比,实体的状态属性是否更改。因为我使用共享相同 ISession 的存储库,当我尝试从数据库中获取实体时,为了得到一个用于比较的对象:
if (fromDbEntity.Status != entity.Status) throw new Exception("Cannot change status...");
我总是会从第一级缓存中获取 fromDbEntity - 所以我处理同一个对象。
有没有办法强制NHibernate / Repository从数据库中获取实体,即使它已经在会话范围内了?
答案 0 :(得分:7)
在加载entity
fromDbEntity
session.Evict(entity);
您可以查看官方文档了解更多详情:Managing the caches
关于这一点的问题是,您需要为SaveOrUpdate
手动调用entity
,因为现在该对象已不在会话中。
答案 1 :(得分:3)
您可以像Claudio suggests一样从会话中逐出entity
,然后加载您的fromDbEntity
,进行比较,然后再次Merge该实体与会话
您可能会做的其他事情是使用stateless session加载fromDbEntity
。
但这真的有必要吗?难道你不能让你的Status
属性只读吗? NHibernate完全能够使用fields来访问数据。或者您可以设置属性设置器protected
:
public virtual Status Status { get; protected set; }
这样用户将无法更改属性值,因此无需检查当前值是否与db 1不同。
答案 2 :(得分:1)
我有一个类似的问题,我通过在任何我想要一直到数据库的电话之前清除会话来解决它。
session.Clear();
这有点矫枉过正,但它确实有效。
答案 3 :(得分:0)
你的逻辑方式,听起来像是一个潜在的错误。一个更好的解决方案是打开动态更新,从而只更新更改的值,然后在保存之前验证没有人更改状态。