问题
I recently have found out how to audit instances with the IPreDeleteEventListener
, IPreInsertEventListener
and IPreUpdateEventListener
in the NHibernate.Event
namespace.
However, it still confuses me what shall these event return either on successful or unsuccessful finality.
For example, let's take a look at Ayende's blog article found here:
- NHibernate IPreUpdateEventListener & IPreInsertEventListener
Following his example, one could implement the interfaces as following:
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;
}
}
What odes it actually mean to return either true
or false
as return value, since I have another example where true
is returned instead of false
as Ayende wrote.
- Soft Deletes With NHibernate
Which seems to return true
instead of 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;
}
}
So I wonder, what false
/true
actually tells NHibernate depending on the listener dealt with.
回答1:
The returned value in this case should be enum, Let's use the name OnPreEventResult
, and these would be the possible values:
OnPreEventResult.Continue
=> to continue currently returnfalse
OnPreEventResult.Break
=> at the moment, when thetrue
is returned the Action is aborted
So, as both examples above show, we can use the return value to manage the execution flow:
to Continue:
If we in theAuditEventListener
return false, we in fact return something likeOnPreEventResult.Continue
. We've made some custome logic, and we want NHibernate to continue... so the false is returnedto Break/Abort:
Ayende's example is showing us how to change the real DELETE into UPDATE. Update is called explicitly@event.Persister.Update(...
and the delete is not executed due to the returned value true, i.e.OnPreEventResult.Break
In the code, the returned values are stored in local variable called veto
, which is again more self descriptive.
See:
- EntityInsertAction, or
- EntityDeleteAction
A snippet from the EntityInsertAction
, the Execute()
method:
...
bool veto = PreInsert();
if (!veto)
{
persister.Insert(id, state, instance, Session);
...
来源:https://stackoverflow.com/questions/21838758/what-false-true-really-mean-for-ipreinserteventlisteners