2008-08-19 71 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