2008-08-19 70 views
15

我在一个项目中使用NHibernate和我需要做数据审计。我在codeproject上找到了this article,讨论了IInterceptor接口。数据审核和SQLServer

您最喜欢审核数据的方式是什么?你使用数据库触发器?你是否使用类似于文章中讨论的内容?

回答

14

对于NHibernate的2.0,你也应该看看Event Listeners。这些是IInterceptor接口的发展,我们成功地将它们用于审计。

3

我更喜欢你提到的CodeProject方法。

与数据库

一个问题触发的是,它让你没有选择,只能使用集成安全性再加上ActiveDirectory的机会获得您的SQL Server。原因是您的连接应该继承触发连接的用户的身份;如果您的应用程序使用指定的“sa”帐户或其他用户帐户,则“用户”字段将仅反映“sa”。

这可以通过为每个和应用程序的每一个用户名为SQL Server的帐户会被覆盖,但是这将是不切实际的非内部网,面向公众的Web应用程序,例如。

+1

有解决办法/替代给每个用户一个SQL帐户或使用集成的身份验证。每当您更新记录时,您可以在您的表上审核“LastUpdatedByUser”列并从应用程序中将其发送出去。触发器可以使用该列的值来填充审计记录。 – 2009-04-08 14:18:46

5

[编辑]

发布NH2.0的发布,请看下面建议的事件监听器。我的回答已过时。


IInterceptor是以非侵入性方式修改nhibernate中的任何数据的推荐方法。如果您的应用程序代码不需要知道,它对解密/加密数据也很有用。

数据库上的触发器将日志记录(应用程序问题)的责任转移到将日志解决方案有效地绑定到数据库平台的DBMS层。通过将审计机制封装在持久层中,您可以保持平台独立性和代码可传输性。

我用拦截器在生产代码在几个大的系统提供审核。

+0

我发现IInterceptor解决方案存在一些问题,例如,“LastUpdated”日期被设置为在客户端工作站上设置的日期,而不是所使用的数据库服务器的日期。 – 2009-05-26 21:07:04

3

我喜欢提到的拦截方法,并以此对我目前工作的项目。

但是,值得强调的一个明显的缺点是,这种方法只会审核通过您的应用程序所做的数据更改。除非您记得同时执行审计表插入操作,否则任何直接数据修改(例如,您可能需要不时执行的临时SQL脚本)都不会被审计。

2

作为一种完全不同的方法,您可以在存储库中使用装饰器模式。

说我有

public interface IRepository<EntityType> where EntityType:IAuditably 
{ 
    public void Save(EntityType entity); 
} 

然后,我们就会有我们的NHibernateRepository:

public class NHibernateRepository<EntityType>:IRepository<EntityType> 
{ 
    /*...*/ 
    public void Save (EntityType entity) 
    { 
     session.SaveOrUpdate(entity); 
    } 
} 

然后,我们可以有一个审计资源库:

public class AuditingRepository<EntityType>:IRepository<EntityType> 
{ 
    /*...*/ 
    public void Save (EntityType entity) 
    { 
     entity.LastUser = security.CurrentUser; 
     entity.LastUpdate = DateTime.UtcNow; 
     innerRepository.Save(entity) 
    } 
} 

然后,使用一个IoC框架(StructureMap,Castle Windsor,NInject)你可以在没有其他代码的情况下全部构建它知道你正在进行审计。

当然,你怎么审计级联集合中的元素是另一个问题完全...

+0

我不认为这是正确的解决方案,除非你明确地调用保存并以某种方式禁用NH的Flush行为。即即使没有调用save方法,对实体的更改也会持续存在! – Rashack 2009-08-17 07:27:31