代码之家  ›  专栏  ›  技术社区  ›  Iain Holder

NHibernate中使用事件的数据审核

  •  9
  • Iain Holder  · 技术社区  · 17 年前

    我正在重新访问并重新实现引起我询问的代码 this question 关于NHibernate中的数据审核。不过这次,我想和你一起去 Sean Carpenter suggestion 并实现ISaveOrUpdateEventListener(NHibernate2.x中新增)

    我想在数据库中为每个属性的每次更改添加一行,包括旧值和新值,以便稍后在UI中可以说 “用户Bob于2009年3月9日21:04将Wibble的属性从A更改为B”

    比较对象状态以确定对象的哪些属性已更改的最佳方法是什么?

    您可以通过以下方式获取对象的加载状态:

        public void OnSaveOrUpdate(SaveOrUpdateEvent saveOrUpdateEvent)
        {
           object[] foo = saveOrUpdateEvent.Entry.LoadedState;
        }
    

    我想我可以使用反射来找出哪些属性发生了变化,但我一直在四处挖掘,似乎没有一组匹配的属性可以比较。我本以为会有一个GetChangedProperties()方法之类的东西。

    我总是可以从数据库中获取旧对象,并对其进行比较,但这是另一个数据库命中率,在这种情况下似乎很难处理。

    最好的方向是什么?

    另外,如果有什么不同,这是一个ASP.NET-MVC/S#arp架构项目。

    3 回复  |  直到 9 年前
        1
  •  11
  •   Darrell Mozingo    17 年前

    您还可以在Persister上使用FindDirty方法,让NHibernate为您进行比较:

    var dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session);
    
    foreach (var dirtyFieldIndex in dirtyFieldIndexes)
    {
        var oldValue = @event.OldState[dirtyFieldIndex];
        var newValue = @event.State[dirtyFieldIndex];
    
        // Log values to new "AuditLog" object and save appropriately.
    }
    
        2
  •  6
  •   mookid8000    17 年前

    我不知道怎样才能用这些钱达到你想要的 ISaveOrUpdateListener IPreUpdateEventListener 和 IPreInsertEventListener 接口都提供您所需要的。。。e、 g.这样做:

    public bool OnPreUpdate(PreUpdateEvent evt)
    {
        string[] names = evt.Persister.PropertyNames;
        for(int index = 0; index < names.Length; index++)
        {
            // compare evt.State[index] to evt.OldState[index] and get
            // the name of the changed property from 'names'
            // (...)
        }
    }
    

        3
  •  0
  •   James L    17 年前

    您可以实现一个Memento模式,通过 ILoadEventListener .