我在一個項目中使用NHibernate和我需要做數據審計。我在codeproject上找到了this article,討論了IInterceptor接口。數據審覈和SQLServer
您最喜歡審覈數據的方式是什麼?你使用數據庫觸發器?你是否使用類似於文章中討論的內容?
我在一個項目中使用NHibernate和我需要做數據審計。我在codeproject上找到了this article,討論了IInterceptor接口。數據審覈和SQLServer
您最喜歡審覈數據的方式是什麼?你使用數據庫觸發器?你是否使用類似於文章中討論的內容?
對於NHibernate的2.0,你也應該看看Event Listeners。這些是IInterceptor接口的發展,我們成功地將它們用於審計。
我更喜歡你提到的CodeProject方法。
與數據庫一個問題觸發的是,它讓你沒有選擇,只能使用集成安全性再加上ActiveDirectory的機會獲得您的SQL Server。原因是您的連接應該繼承觸發連接的用戶的身份;如果您的應用程序使用指定的「sa」帳戶或其他用戶帳戶,則「用戶」字段將僅反映「sa」。
這可以通過爲每個和應用程序的每一個用戶名爲SQL Server的帳戶會被覆蓋,但是這將是不切實際的非內部網,面向公衆的Web應用程序,例如。
[編輯]
發佈NH2.0的發佈,請看下面建議的事件監聽器。我的回答已過時。
IInterceptor是以非侵入性方式修改nhibernate中的任何數據的推薦方法。如果您的應用程序代碼不需要知道,它對解密/加密數據也很有用。
數據庫上的觸發器將日誌記錄(應用程序問題)的責任轉移到將日誌解決方案有效地綁定到數據庫平臺的DBMS層。通過將審計機制封裝在持久層中,您可以保持平臺獨立性和代碼可傳輸性。
我用攔截器在生產代碼在幾個大的系統提供審覈。
我發現IInterceptor解決方案存在一些問題,例如,「LastUpdated」日期被設置爲在客戶端工作站上設置的日期,而不是所使用的數據庫服務器的日期。 – 2009-05-26 21:07:04
我喜歡提到的攔截方法,並以此對我目前工作的項目。
但是,值得強調的一個明顯的缺點是,這種方法只會審覈通過您的應用程序所做的數據更改。除非您記得同時執行審計表插入操作,否則任何直接數據修改(例如,您可能需要不時執行的臨時SQL腳本)都不會被審計。
作爲一種完全不同的方法,您可以在存儲庫中使用裝飾器模式。
說我有
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)你可以在沒有其他代碼的情況下全部構建它知道你正在進行審計。
當然,你怎麼審計級聯集合中的元素是另一個問題完全...
我不認爲這是正確的解決方案,除非你明確地調用保存並以某種方式禁用NH的Flush行爲。即即使沒有調用save方法,對實體的更改也會持續存在! – Rashack 2009-08-17 07:27:31
我理解,這是一個老問題。但是我想根據NH 2.0中的新事件系統來回答這個問題。事件監聽器比攔截器更適合審計類功能。 Ayende上個月在他的博客上寫了一個很好的例子。這裏的URL到他的博客 -
有解決辦法/替代給每個用戶一個SQL帳戶或使用集成的身份驗證。每當您更新記錄時,您可以在您的表上審覈「LastUpdatedByUser」列並從應用程序中將其發送出去。觸發器可以使用該列的值來填充審計記錄。 – 2009-04-08 14:18:46