更改完成后,NHibernate PreUpdateEvent将触发

时间:2014-01-17 21:19:52

标签: c# nhibernate

当我访问PreUpdateEvent时,我会获得包含更新数据的实体 我假设pre update会在db中更新之前给我数据。

preUpdateEvent.Entity - 提供新数据。 preUpdateEvent.State - 提供新数据。

// Even when I go to the database and ask the persisted entity, 
//  I get it with the changes.
preUpdateEvent.Session.Get(typeof(preUpdateEvent.Entity), preUpdateEvent.Entity.Id);

如何访问OnPreUpdate(PreUpdateEvent preUpdateEvent)中的持久化实体,以便我可以将其审核到审核表?

更新

public bool OnPreUpdate(PreUpdateEvent preUpdateEvent)
{
    var persisted = preUpdateEvent.Session.Merge(preUpdateEvent.Entity);
    return false;
}

因此,在合并有新数据后,var仍然存在 我希望坚持使用旧数据(预更新)。

2 个答案:

答案 0 :(得分:3)

PreUpdateEvent Listener 会像这样被调用

bool OnPreUpdate(PreUpdateEvent @event); 

,有关实体的完整信息将作为@event参数传递,该参数的类型为class PreUpdateEvent。所以我们有访问属性:

/// <summary> The entity involved in the database operation. </summary>
public object Entity { get; }
/// <summary> The id to be used in the database operation. </summary>
public object Id { get; }
/// <summary>
/// Retrieves the state to be used in the update.
/// </summary>
public object[] State { get; }
/// <summary>
/// The old state of the entity at the time it was last loaded from the
/// database; can be null in the case of detached entities.
/// </summary>
public object[] OldState { get; }

我们可以获取所有信息,最新更改State以及之前的值OldState

在此阶段(事件)中,我们无法调用session.get() ...因为已经存在“更新的”对象。在这种情况下,会话不会以DB为目标。

正如评论所说:如果对象来自外部世界(客户端,服务层)并通过Update()传递给会话,则OldState可能为NULL。为避免这种情况,我们可以致电session.Merge(ourInstance) 修复很多问题。请参阅:9.4.2. Updating detached objects

EXTEND:OldState如何运作?

1)我们要么通过sessin.GetById(id)加载对象。会话上有,而我们正在修改该实例。最后,我们调用session.Flush()在DB中执行UPDATE语句。在这种情况下,NHibernate确实拥有一切可控制的内容...... OldState已正确填充。

2)或者我们确实从外部(不是session)世界接收数据,由分离的实例表示。在这种情况下,NHibernate无法跟踪更改。它只有通过session.Update(instance)传递的最新信息,而在Flush()上它确实触发了PreUpdate事件,但没有旧状态。

在这种情况下,我们可以调用session.Merge(instance)而不是Update(),NHibernate将从DB 加载对象(因此将具有之前的值)< / em>,使用合并实例附带的最新设置更新它们,并使用完整信息触发PreUpdate事件。

答案 1 :(得分:0)

也许在这个新会话中创建新会话和合并对象,您将获得OldState