我剛纔問了一個類似的問題。 Audit Logging Strategies也看這個問題的另一種方式 how-do-i-implement-changetime-and-changeuser-columns-using-nhibernate
我最終什麼事落實IInterceptor爲一類,幷包含實體類型的通用審計日誌POCO類,實體ID,屬性名稱,當前狀態,以前的狀態,更改類型(插入,更新,刪除)以及更改發生的日期時間。
然後,我創建了一個空的接口IAuditable接口,使每個我想要審計類可以被識別。
在OnFlushDirty,OnDelete而且我現在不能想別的事件,增加了新的審計日誌類是改變了每個屬性。
,當我回家我會更新這個問題,並有機會獲得我目前正在使用的代碼。
也期待 Frederik Gheysels' DevLog - NHibernate IInterceptor: an AuditInterceptor
編輯 - 更新應答與實施
看它再次我需要重構它,因爲它沒有很多氣味,但當時我只是需要一些工作,而這是我想出來的。
這是我已經使用
<class name="AuditLog" table="AuditLog" lazy="true" >
<id name="_persistenceId" column="Id" type="Guid" access="field" unsaved-value="00000000-0000-0000-0000-000000000000" >
<generator class="guid.comb" />
</id>
<version name="_persistenceVersion" column="RowVersion" access="field" type="int" unsaved-value="0"/>
<property name="CreatedDate" column="CreatedDate" type="DateTime" />
<property name="UpdatedBy" column="UpdatedBy" type="string" length="100" />
<property name="EntityID" column="EntityID" type="guid" not-null="true" />
<property name="EntityName" column="EntityName" type="String" length="100" not-null="true" />
<property name="PropertyName" column="PropertyName" type="String" length="100" not-null="true" />
<property name="ActionType" column="ActionType" type="Char" length="1" not-null="true" />
<property name="OldValue" column="OldValue" type="String" length="1000" not-null="false" />
<property name="NewValue" column="NewValue" type="String" length="1000" not-null="false" />
</class>
類是實現每個這些屬性的一般POCO類NHibernate的映射。
的IInterceptor的Implemetation像這樣(在VB.Net)
Imports Rhino.Commons
Public Class AuditInterceptor
Inherits NHibernate.EmptyInterceptor
Private _auditLogRepository As IAuditLogRepository
Public Sub New(ByVal [AuditLogRepository] As IAuditLogRepository)
_auditLogRepository = [AuditLogRepository]
End Sub
Public Overrides Function OnFlushDirty(ByVal entity As Object, ByVal id As Object, ByVal currentState() As Object, ByVal previousState() As Object, ByVal propertyNames() As String, ByVal types() As NHibernate.Type.IType) As Boolean
'Called on an Update
If TypeOf entity Is IAuditable Then
Using uow = UnitOfWork.Start(UnitOfWorkNestingOptions.CreateNewOrNestUnitOfWork)
If TypeOf entity Is [yourObject] Then
aLog = New AuditLog(Now, My.User.Name)
With aLog
.EntityID = id
.EntityName = "[yourObject]"
.PropertyName = "[yourProperty]"
.ActionType = "U"
.OldValue = GetPropertyValue("[yourProperty]", previousState, propertyNames)
.NewValue = GetPropertyValue("[yourProperty]", currentState, propertyNames)
End With
_auditLogRepository.Save(aLog)
End if
uow.Flush()
End Using
End If
Return MyBase.OnFlushDirty(entity, id, state, propertyNames, types)
End Function
Public Overrides Function OnSave(ByVal entity As Object, ByVal id As Object, ByVal state() As Object, ByVal propertyNames() As String, ByVal types() As NHibernate.Type.IType) As Boolean
'Called on an Insert
If TypeOf entity Is IAuditable Then
'create a new audit log class here
end if
Return MyBase.OnSave(entity, id, state, propertyNames, types)
End Function
是相同的事務中主要實體保存審計日誌? – dariol 2009-09-11 17:36:23
對我來說,它應該是同一事務的一部分,這就是爲什麼我使用UnitOfWork.Start(UnitOfWorkNestingOptions。CreateNewOrNestUnitOfWork),以便它加入當前的UOW。我知道我在這個領域遇到問題,當我試圖讓它工作。使用CreateNewOrNestUnitOfWork選項作爲UOW的一部分產生了不同。 – 2009-09-14 23:09:05