2014-02-17 71 views
1

我最近已经找到了如何使用NHibernate.Event名称空间中的IPreDeleteEventListener,IPreInsertEventListenerIPreUpdateEventListener来审计实例。对于IPreInsertEventListeners,真假意味着什么?

但是,它仍然让我困惑,这些事件会以成功或失败的结局返回。

例如,让我们来看看Ayende的博客文章在这里找到:

在他的例子,一个可以实现的接口如下:

public class AuditEventListener : IPreInsertEventListener { 
    public bool OnPreInsert(OnPreInsert @event) { 
     var audit = @event.Entity as IHaveAuditInformation; 
     if (audit == null) return false; 

     var time = DateTime.Now; 
     var name = WindowsIdentity.GetCurrent().Name; 

     Set(@event.Persister, @event.State, "CreatedAt", time); 
     Set(@event.Persister, @event.State, "CreatedBy", name); 

     audit.CreatedAt = time; 
     audit.CreatedBy = name; 

     return false; 
    } 
} 

它实际上意味着返回truefalse作为返回值,sinc e我有另一个例子,其中true返回而不是false Ayende写道。

这似乎回到true而不是false

public class SoftDeletableListener : IPreDeleteEventListener { 
    public void Register(Configuration cfg) { 
     cfg.EventListeners.PreDeleteEventListeners = 
      new IPreDeleteEventListener[] { this } 
       .Concat(cfg.EventListeners.PreDeleteEventListeners) 
       .ToArray(); 
    } 

    public Boolean OnPreDelete(PreDeleteEvent @event) { 
     ISoftDeletable softDeletable = @event.Entity as ISoftDeletable; 

     if (softDeletable == null) return true; 

     EntityEntry entry = @event.Session 
      .GetSessionImplementation() 
      .PersistenceContext 
      .GetEntry(@event.Entity); 
     entry.Status = Status.Loaded; 

     softDeletable.Deleted = true; 

     Object id = @event.Persister 
      .GetIdentifier(@event.Entity, @event.Session.EntityMode); 
     Object [] fields = @event.Persister 
      .GetPropertyValues(@event.Entity, @event.Session.EntityMode); 
     Object version = @event.Persister 
      .GetVersion(@event.Entity, @event.Session.EntityMode); 

     @event.Persister.Update(id 
      , fields 
      , new Int32[1] 
      , false 
      , fields 
      , version 
      , @event.Entity 
      , null 
      , @event.Session.GetSessionImplementation()); 

     return true; 
    } 
} 

所以我想知道什么false/true实际上告诉NHibernate的取决于听者处理。

+0

在'SoftDeletableListener'例如,当不可t是'if(softDeletable == nul l)返回false;'('false'而不是'true')?否则不会删除任何实体,无论它是否是“ISoftDeletable”。 – lalibi

回答

3

在这种情况下,返回值应为枚举,让我们用名字OnPreEventResult,而这些将是可能的值:

  • OnPreEventResult.Continue =>继续目前返回false
  • OnPreEventResult.Break =>此刻,当true返回行动中止

所以,如上图所示两个例子中,我们可以使用返回值来管理执行流程:

  1. 以继续
    如果我们在AuditEventListener回报,我们实际上返回类似OnPreEventResult.Continue。我们已经取得了一些custome逻辑,我们希望NHibernate的继续......所以返回

  2. 玩转/中止
    Ayende的例子向我们展示如何改变现实DELETE成UPDATE。更新显式调用@event.Persister.Update(...和删除是由于返回值执行,即OnPreEventResult.Break

在代码中,返回的值存储在一个名为veto局部变量,这又是更自我描述。

参见:

EntityInsertAction甲片段中,Execute()方法:

... 
bool veto = PreInsert(); 

if (!veto) 
{  
    persister.Insert(id, state, instance, Session); 
... 
+0

+1感谢您的好解释!我现在更好地了解发生了什么。这些例子,恕我直言,如果他们实际上使用了这个'OnPreventResult'枚举,它将会更简洁。谢谢@Radim! –

+0

伟大的,如果这有帮助无论如何。享受NHibernate :) –

+0

很好的解释。 实际上这个例子是错误的。如果这个类没有实现“软删除”合约,那么拦截器应该返回false而不是true。 – Raffaeu