3

我目前正在开发一个 ASP.NET 人力资源系统。我正在使用基于 MVP 模式的带有 Web 客户端软件工厂的分层架构。ORM 是 NHibernate。我需要实现一个审计日志模块。我读过很多关于不同方法的文章。他们中的大多数都描述了如何跟踪日期、时间戳和进行更改的人的身份,但没有人能告诉我那个:如何跟踪我的域层中任何属性的更改?我不需要任何回滚功能,我只需要记录:更改对象的谁、何时和什么属性,该属性的旧值和新值。

我无法决定将这些更改的处理程序放在哪里。Fowler 在属性的 setter 方法中指出了一个 Audit Log,但我仍然想保持我的域类简单 POCO。也许还有其他方法?

4

4 回答 4

2

几年前我也不得不为人力资源系统做这件事。我完成了它,让我所有的“字段”都实现了一个模板(通用):

这是我修剪的模板示例:

class DataField<T>
{
    public T Current { get; set; }
    public T Original { get; set; }
    // stores the field name as a nice textual readable representation.
    // would default to property name if not defined.
    public string FieldName { get; set; }
    public bool Modified
    {
        get { return !(Current.Equals(Original));
    }

    public DataField(T value)
    {
        Original = Current = value;
    }

    public DataField(T value, T fieldName)
    {
        Original = Current = value;
        FieldName = fieldName;
    }
}

使审计变得容易的有趣部分是每个对象都可以生成自己的审计日志。我可以获取任何可能具有 x 个这些“字段”的对象并在其上调用 GetAudit,它会返回一个审核对象,其中包含对显示字段名称、旧 val、新 val 等的类的所有更改。每个'DataField' 将实现一个返回审计对象的方法。对于字符串、双精度、整数等,它几乎已经融入其中,但如果您使用自定义对象,您可以为它们编写审计实现,只需要返回一个审计对象。

因此,在最后的典型形式中,我会将所有数据存储在一个具有所有这些类型字段的对象中。然后我会进行更新并调用 GetAudit 方法,该方法也将写入审计表。

即使他们必须浏览多个页面等,我也可以轻松判断表单中是否有任何更改。

撤消在逐个字段、逐个部分或整个对象级别上非常容易。

由于我很长时间没有接触过代码,所以对确切的细节有点模糊,但这就是它的要点。希望有帮助。

于 2009-06-26T01:40:19.170 回答
0

但是,也许您可​​以实现观察者模式,因为.net 隐式地​​(通过事件)实现了这种模式,我认为不会有太多附加值。

也许您可以保存“原始”对象并在适当的时候将它们与修改后的对象进行比较(可能使用反射),并找出哪些属性已更改以及它们的新值是什么。但是,请注意,您不能在 .net 中对对象进行深度复制(除非您可以序列化对象),因此请记住此解决方案

于 2009-06-24T20:12:28.667 回答
0

您需要将原始数据保留在对象中,或者在更新之前将其从数据库中提取以进行记录。

我已经在数据层看到了这一点,无论是在存储过程还是触发器中,但从未在域层中实现。

编辑:在这里可以找到使用数据库触发器记录历史记录的 2 部分示例:http : //www.4guysfromrolla.com/webtech/041807-1.shtml 关于这种技术的优缺点似乎有很多很好的讨论。我希望这会有所帮助。

于 2009-06-24T20:28:32.813 回答
-1

您是否查看过 Microsoft Enterprise Library的Logging Application Block ?

于 2009-06-24T20:20:34.140 回答