我正在使用NHibernate拦截器将有关更新/插入/删除的信息记录到我的各种实体。
记录的信息中包括实体类型和已修改实体的唯一ID。唯一ID在NHibernate映射文件中标记为<generator class="identity">
。
明显的问题是当使用IInterceptor.OnSave()记录Insert操作时,尚未分配实体的Id。
如何在记录审核信息之前获取插入实体的ID?
(我已经研究过NHibernate Listeners PostSave事件,但无法使用正在使用的Spring.net配置,所以我想尽可能坚持使用拦截器)
代码:
// object id parameter is null...
public override bool OnSave(object entity, object id, object[] state,
string[] propertyNames, IType[] types)
{
AddAuditItem(entity, INSERT);
return false;
}
答案 0 :(得分:8)
我通过在我的拦截器类中添加一个列表解决了这个问题,该类在OnSave
实现期间填充了对象。
在PostFlush
实现中,迭代列表,并将每个元素作为插入进行审计。此列表中的对象已保留在PostFlush()
中,因此生成了ID。
这似乎工作正常,但如果指出任何潜在的陷阱,我将不胜感激: - )
public class AuditInterceptor : EmptyInterceptor
{
// To hold inserted items to be audited after insert has been flushed
private IList<object> insertItems = new List<object>();
public override void PostFlush(System.Collections.ICollection entities)
{
foreach (var entity in insertItems)
{
AddAuditItem(entity, INSERT);
}
insertItems.Clear();
base.PostFlush(entities);
}
public override bool OnSave(object entity, object id, object[] state,
string[] propertyNames, IType[] types)
{
var auditable = entity as IAuditable;
if (auditable != null)
insertItems.Add(entity);
return false;
}
}
答案 1 :(得分:0)
尝试OnFlushDirty
方法..或者PostFlush
编辑:另外,你可以发布你的代码吗?你不能将Id作为OnSave
的参数吗?