代码之家  ›  专栏  ›  技术社区  ›  David Archer Chris Spicer

如何在NHibernate中进行通用字段和组件级别更改跟踪?

  •  3
  • David Archer Chris Spicer  · 技术社区  · 15 年前

    在我的应用程序中,我有几个不同类型的实体需要对它们进行字段级更改跟踪。我已经在谷歌上搜索过了,只能想出一些简单的“插入日期”和“更新日期”审计跟踪的例子,您只需在其中修改被持久化的实体上的字段即可。我的要求更复杂,因为:

    1. 我需要创建代表更改的新实体,而不仅仅是修改正在保存的实体上的字段(如插入日期,我找到的更新日期示例)
    2. 我需要在同一个事务中将这些新实体保存到数据库中,更新跟踪的实体
    3. 我需要跟踪附加到被跟踪实体的ValueObjects集合的更改
    4. 我不想为每个被跟踪的实体编写单独的日志代码

    示例代码:

    public interface ITrackChanges {}
    {
    }
    
    public class Account : ITrackChanges
    {
        public int Id;
        public string AccountNumber;
        public string CustomerName;
        public string CustomerAddress;
    }
    
    public class Computer : ITrackChanges
    {
        public int Id;
        public string AssetTag;
        public string SerialNumber;
        public IEnumerable<IPAddress> IPAddresses;
    }
    
    public class IPAddress : ValueObject
    {
        public string Address;
    }
    

    每当帐户或计算机对象的任何值更改或与计算机对象关联的IP地址列表更改时,我需要创建并保存这些实体更改记录:

    public class EntityChange
    {
        public string EntityType;
        public string EntityId;
        public string PropertyName;
        public string OldValue;
        public string NewValue;
    }
    

    每个被跟踪的实体实现ITrackChanges标记接口,每个值对象从ValueObject基类继承。值对象在nhibernate中映射为组件。

    作为我希望得到的最终结果的一个例子,如果我用id 1更新计算机对象,并将assettag从“abc123”更改为“abc124”,并将IP地址列表从“1.2.3.4”更改为“1.2.3.4”、“1.2.3.5”,我应该得到2个entityChange记录:

    EntityChange #1
    {
        EntityType = "Computer"
        EntityId = 1
        PropertyName = "AssetTag"
        OldValue = "ABC123"
        NewValue = "ABC124"
    }
    
    EntityChange #2
    {
        EntityType = "Computer"
        EntityId = 1
        PropertyName = "IPAddresses"
        OldValue = "1.2.3.4"
        NewValue = "1.2.3.4, 1.2.3.5"
    }
    

    关于实现这一点的最佳方法有什么想法吗?从我对文档的阅读来看,我似乎需要编写一个拦截器和/或事件监听器,但除了一些可以修改正在更新的实体的示例外,我还没有找到其他示例。示例代码在任何答案中都是绝对受欢迎的。

    假设这应该是由NHibernate支持的,我错了吗?我可以在以前使用llblgen作为ORM的应用程序中实现这一点,但这是我第一次必须在使用nhibernate的应用程序中实现这一点。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Aaron Fischer    15 年前

    你想要的是使用一个会话接口。 您可以找到将此用于审核的示例 here

    此外,您可能会从 NHibernate mail list .