NHibernate 3.2-删除前和删除后事件监听器

Nat*_*lor 0 c# nhibernate

我正在使用几个自定义实体状态更改侦听器反对NHibernate 3.2的实现:PreDelete,Delete和PostDelete。DeleteEventListener是通过从DefaultDeleteEventListener继承自定义类型定义的,但是其他方法只是在实现IEventListener接口。

CustomDeleteEventListener的主体如下:

protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
{
    if (entity is BaseEntity)
        HandleEntityAssociations(session, (BaseEntity)entity);

    if (entity is ISoftDeletable) 
    {  
        var e = (ISoftDeletable)entity;
        Utility.SetTrackingInfo(e as BaseModel);

        e.Deleted = true; 

        CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities); 
        CascadeAfterDelete(session, persister, entity, transientEntities); 
    } 
    else 
    { 
        base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities); 
    } 
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我发现OnDelete()听众总是被调用之前OnPreDelete()OnPostDelete()听众,以及前置和后置的听众永远不会火,如果base.DeleteEntity()不叫。这没有任何意义,我-我期望的顺序为:OnPreDelete()OnDelete()OnPostDelete()

当我检查调用堆栈时,我注意到调用OnDeleteEvent()是由对的FireDelete()直接调用触发的,该调用是在调用之后立即调用的ISession.Delete(),但OnPreDeleteEvent()被监听器触发OnFlush()-与完全断开连接OnDeleteEvent()

这些侦听器几乎没有文档,只有少数博客使用此对象。有谁知道它们在NHibernate 3.2中是如何工作的,为什么我看到自己的行为?

Ale*_*lex 5

从我的理解中,OnDeleteOnUpdate,...是用来做这样的事情的验证,或者修改实际的实体被删除,更新,插入。这几乎发生在管道的开始,请参见“ NHibernate拦截器魔术技巧,第4页”。

当删除发生时,NHibernate所做的第一件事就是调用IInterceptor.OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types)方法。它不提供任何流控制,IDeleteEventListener在计划实际的删除操作之前,默认情况下只是简单地调用它。

另请参阅该博客系列的其他部分以获取更多信息。

PreDeletePostDelete事件监听器调用的DeleteAction,它本身是由创建DefaultDeleteEventListener 它(你是从派生即类)DeleteEntity方法,并添加到会话的行动队列中。因此,他们被调用DeleteEventListenerinvokation。

这些Pre...事件仅在发出实际命令之前发生。那时,通过修改实体本身来强制对命令进行更改为时已晚,尽管您可以使用命令的参数(并确保也将这些更改应用于相应的实体的字段),或执行其他操作(例如,插入审核记录)。返回true从这些的Pre...听众将否决变更,返回false将导致执行它。

您可能需要阅读此博客文章:NHibernate IPreUpdateEventListener和IPreInsertEventListener。它与更新和插入侦听器有关,但是对于删除,其推理将相似。

这些允许我们在将更新/插入发送到数据库之前执行定制逻辑。从表面上看,这似乎是一项琐碎的任务,但是在使用它们时,我们需要考虑一些细微之处。

这些钩子在处理管道中运行得很晚,这是使它们如此有用的部分原因,但是由于它们运行得太晚了,所以当我们使用它们时,我们必须知道我们对它们的处理方式及其对其余部分的影响的应用程序。

看来“晚了”意味着:

事件侦听器完成运行后将立即执行的ADO.Net命令。

由于NHibernate牢固地扎根于Java Hibernate版本,该版本具有相同的侦听器和事件类型,因此这是有关此主题的更多正式文档的另一个潜在信息来源。