2009-04-16 113 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的對象執行審計。