Я задал похожий вопрос некоторое время назад.
Audit Logging Strategies также посмотрите на этот вопрос по-другому
как-делать-я орудие-changetime-и-changeuser-колонки-используя-NHibernate
В итоге я реализовал IInterceptor как класс и универсальный poco-класс Auditlog, который содержал тип сущности, идентификатор сущности, имя свойства, текущее состояние, предыдущее состояние, тип изменения (Вставка, Обновление, Удаление) и дата и время, когда произошло изменение.
Затем я создал пустой интерфейс IAuditable, чтобы можно было идентифицировать каждый класс, который я хотел проверить.
В OnFlushDirty, OnDelete и другом событии, о котором я сейчас не могу думать, добавлены новые классы аудита для каждого измененного свойства.
Я обновлю этот вопрос, когда вернусь домой и у меня будет доступ к коду, который я сейчас использую.
Также смотри
DevLog Фредерика Гейселя - NHibernate II Интерцептор: AuditInterceptor
Редактировать - Обновление ответа с реализацией
Глядя на это снова, мне нужно провести рефакторинг, так как он пахнет много, но в то время мне просто нужно было что-то работать, и это то, что я придумал.
Это отображение nhibernate, которое я использовал
<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, который реализует каждое из этих свойств.
Реализация II-рецептора выглядит так (в 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