c# - 更改完成后触发 NHibernate PreUpdateEvent

标签 c# nhibernate

当我访问 PreUpdateEvent 时,我会获取包含更新数据的实体。
我假设预更新会给我数据库中更新之前的数据。

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 在合并有新数据后仍然存在。
我想保留旧数据(更新前)。

最佳答案

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() ...因为已经存在“更新的”对象。在这种情况下, session 不会以数据库为目标。

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

扩展:OldState 是如何工作的?

1) 我们要么通过 sessin.GetById(id) 加载对象。当我们修改该实例时,Session 已经掌握了它。最后,我们调用session.Flush()来在DB中执行UPDATE语句。在这种情况下,NHibernate 确实控制了一切...OldState 已正确填充。

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

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

关于c# - 更改完成后触发 NHibernate PreUpdateEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21196078/

相关文章:

c# - 使用 Swashbuckle 5.x 在通用 T 参数引用属性上指定 nullable = true

c# - Windows 服务的全局异常处理程序?

c# - 无法让 Linux 容器在隔离进程中作为 Azure 函数运行

c# - 需要领域建模建议 - 希望是常见场景

c# - XmlSerializer : serializing a class property as an attribute of a custom subelement

c# - 限制属性的字符串长度

security - NHibernate 和共享网络托管

.net - NHibernate 数据访问而不卡住 GUI

c# - 在 Nhibernate 中执行简单的过程调用

nhibernate - 什么是 NHibernate 中的 Tuplizer