问题描述
我想实现我的实体简单的审计。审计实体实施 ITimestampable
接口,它定义了 DateAdded
和 DateModified
属性。
I'm trying to implement simple auditing on my entities. Auditable entities implement the ITimestampable
interface which defines DateAdded
and DateModified
properties.
我创建并注册一个事件侦听器来填充这些值。这里是完整的代码
I created and registered a event listener to populate these values. Here is the complete code.
internal class TimeStampEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
public bool OnPreUpdate(PreUpdateEvent e)
{
if (e.Entity is ITimestampable)
{
(e.Entity as ITimestampable).DateModified = DateTime.Now;
}
return false;
}
public bool OnPreInsert(PreInsertEvent e)
{
if (e.Entity is ITimestampable)
{
(e.Entity as ITimestampable).DateAdded = DateTime.Now;
}
return false;
}
public void Register(Configuration configuration)
{
configuration.SetListener(ListenerType.PreInsert, this);
configuration.SetListener(ListenerType.PreUpdate, this);
}
}
现在,当我提出一个会话红晕,监听器被调用,审计属性都设置正确,但大多数时候他们不会保存到数据库。通过大部分时间我的意思是很少的价值真正得到坚持。我不知道,但它看起来像上的应用程序启动后的第一个插入/更新,这更加怪异。
Now, when I make a session flush, the listener gets called, audit properties are correctly set, but most of the time they are not saved to the DB. By "most of the time" I mean that very rarely the values actually get persisted. I'm not sure, but it looks like on the first insert/update after the app is started, which is even more weird.
当然,首先我做一个更改为实体的变化仍然存在,但审计属性不是。
Of course, first I make a change to the entity, the change is persisted, but the audit property is not.
当我看到在事件探查器生成的SQL我看到NULL是寄于查询,而不是当前的时间,所以我猜它不是一个DB的问题。顺便说一句。我使用MySQL和 DateAdded
和 DateModified
列是日期
键入
When I look at the generated SQL in the profiler I see that NULL is send in the query instead of the current time, so I'm guessing it is not a DB issues. Btw. I'm using MySQL and DateAdded
and DateModified
column are DATE
type.
在NHibernate的网站,这些属性映射仅作为<性>
。也许我错过了一些特殊的映射,这样的情况下...?
On the NHibernate site these properties are mapped only as <property>
. Maybe I'm missing some "special" mapping for cases like these... ?
我完全停留在此。任何形式的帮助表示赞赏。
I'm completely stuck on this. Any kind of help is appreciated.
推荐答案
答案将被隐藏/这表明从Ayende的文章引用
The answer would be hidden/revealed in this cites from Ayende's article
- NHibernate IPreUpdateEventListener & IPreInsertEventListener
...这里说到的精妙,但是。我们不能只更新实体状态。这其中的原因很简单,是从实体状态实体和地方,任何更改,我们对实体状态将不会反映在实体本身中提取的实体状态。可能导致数据库行和走出去同步,并引起一大堆真的讨厌的问题,你不知道从哪里开始调试实体实例。
您必须更新两个在这两个事件侦听器实体和实体状态(这个不一定在其他听众的情况下,顺便说一句)。下面是使用这些事件侦听器的一个简单的例子:
You have to update both the entity and the entity state in these two event listeners (this is not necessarily the case in other listeners, by the way). Here is a simple example of using these event listeners:
这是显示的代码如何,从同一篇文章:
This is the code showing how to, from the same article:
public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
public bool OnPreUpdate(PreUpdateEvent @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, "UpdatedAt", time);
Set(@event.Persister, @event.State, "UpdatedBy", name);
audit.UpdatedAt = time;
audit.UpdatedBy = name;
return false;
}
public bool OnPreInsert(PreInsertEvent @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, "UpdatedAt", time);
Set(@event.Persister, @event.State, "CreatedBy", name);
Set(@event.Persister, @event.State, "UpdatedBy", name);
audit.CreatedAt = time;
audit.CreatedBy = name;
audit.UpdatedAt = time;
audit.UpdatedBy = name;
return false;
}
和这里是神奇的设置()
private void Set(IEntityPersister persister, object[] state
, string propertyName, object value)
{
var index = Array.IndexOf(persister.PropertyNames, propertyName);
if (index == -1)
return;
state[index] = value;
}
这篇关于NHibernate的IPreUpdateEventListener,IPreInsertEventListener不保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!