2009-04-16 52 views
4

我目前正在使用NHibernate开发ASP.NET MVC项目,我需要跟踪一些实体的变化,以便能够对数据进行一些报告和查询。出于这个原因,我希望将数据放在表中,但我试图决定在哪里“挂钩”审计代码。把审计或日志记录放在哪里?

在NHibernate的层:

  • PRO:强大的事件系统来跟踪任何变化
  • PRO:没有任何东西可以在应用程序中进行更改,恕不另行通知(除非有人使用原始SQL ...)
  • CON:因为我有一个通用的存储库...那么我必须过滤出有用的实体(我不需要跟踪所有内容)。
  • CON:我无法轻松访问控制器和操作,因此我只能跟踪基本操作(更新,删除...)。我至少可以获取HttpContext来获取一些信息。

论控制器级别的行为过滤器:

  • PRO:在请求和Web应用程序状态的全部信息。通过这种方式,我可以将“编辑”与“状态更改”区分开来,并在审计信息中更具描述性。
  • CON:有人可以忘记过滤器,可以在不通知的情况下采取重要措施,这是一个很大的挑战。

任何线索?

更新:请参阅如何Create an Audit Log using NHibernate Events

回答

4

我认为在存储库级别执行此操作会更好。主要是因为您将来可能会决定添加一些访问存储库的方法,这些方法不会通过MVC(例如,数据的WCF接口)。

所以问题就变成了,你如何解决你在NHibernate层上做的事情?

过滤出有用的实体非常简单。我可能会通过实体类型的自定义属性来完成此操作。你可以标记你想跟踪的实体,或者你不需要的实体;以较轻者为准。

找出控制器的真正意图是什么更难。我会争辩说你可以“获得HttpContext”;我认为在存储库中这样做不是一个好主意,因为关注的分离。存储库不应该依赖于网络。一种方法是在存储库上为想要以不同方式跟踪的操作创建自定义方法;如果这些编辑的其他方面具有不同的行为,例如不同的安全性,这是特别有吸引力的。另一种方法是通过比较对象的旧版本和新版本来检查更改,并导出更改的实际性质。第三种方法是不要尝试导出更改的性质,而只是将日期和日期之前的版本存储在日志中,以便读取日志的人可以自己找出它。

+1

第四种方法是让控制器提供描述数据库操作的强制性“注释”参数。 – 2009-04-16 12:16:34

1

我宁愿把它放在数据(NHibernate在你的情况下)层。把它放在控制器中,并要求其他人(或者你自己,未来)实施控制器,这与面向对象的设计原则相冲突。

1

我这样做与NHibernate。需要审计的对象实现IAudtable接口,并使用Interceptor通过拦截OnFlushDirty,OnDelete和OnSave对任何实现IAuditable的对象执行审计。