[英]nhibernate auditing with events on update
以下代码适用于插入,但从未设置更新modifier
,有什么想法吗?
预更新代码正在运行并将 state 和实体值正确设置为所需值。 但是查看生成的 sql 时 nhibernate 不包括更新查询中的字段。
/// <summary> Updates auditable objects </summary>
public class AuditEventListener : IPreInsertEventListener, IPreUpdateEventListener
{
private ISecurityManager securityManager;
public bool OnPreInsert( PreInsertEvent args )
{
var auditable = args.Entity as IAuditable;
if (auditable != null) {
Set( x => auditable.Creator, args.Persister, auditable, args.State, SecurityManager.Identity );
Set( x => auditable.DateAdded, args.Persister, auditable, args.State, Clock.Now );
}
return false;
}
public bool OnPreUpdate( PreUpdateEvent args )
{
var auditable = args.Entity as IAuditable;
if (auditable != null) {
Set( x => auditable.Modifier, args.Persister, auditable, args.State, SecurityManager.Identity );
//Set( x => auditable.DateModified, args.Persister, auditable, args.State, Clock.Now );
}
return false;
}
/// <summary> Type safe method to update sate and entity </summary>
private void Set<T, U>( Expression<Func<U, T>> expression, IEntityPersister persister, U instance, object[] state, T value )
{
var member = expression.Body as MemberExpression;
if (member != null) {
var index = Array.IndexOf( persister.PropertyNames, member.Member.Name );
if (index == -1) {
return;
}
state[index] = value;
var property = (member.Member as PropertyInfo);
if (property != null) {
property.SetValue( instance, value, null );
}
}
}
ISecurityManager SecurityManager
{
get { /* From IoC */ }
}
}
编辑1:这个答案有所改进
编辑2:看来在这个问题的真正cuase是动态更新设置为true 这里找到不过这个解决方案仍然为我工作。
在先前调用的OnFlushDirty函数中更新它们时,将保存更改。
public override bool OnFlushDirty( object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types )
{
bool result = false;
if (entity is IAuditable) {
var auditable = (IAuditable)entity;
Set( x => auditable.Modifier, propertyNames, auditable, currentState, SecurityManager.Identity );
//Set( x => auditable.DateModified, args.Persister, auditable, args.State, TwentyClock.Now );
result = true;
}
return result;
}
对我们来说,这是因为 NHibernate 将具有相同列名的表连接在一起; 所以我们会更新该列名的第一个实例,但不会更新后续的实例。 我们这样做了:
protected void Set(IEntityPersister persister, object[] state, string propertyName, object value)
{
var index = Array.IndexOf(persister.PropertyNames, propertyName);
while (index > -1)
{
state[index] = value;
index = Array.IndexOf(persister.PropertyNames, propertyName, index + 1);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.