私は同様の質問をしばらく前に聞いた。 Audit Logging Strategiesはまた別の方法のためにこの質問を見て 私はクラスとエンティティタイプが含まれて一般的な監査ログのPOCOクラス、エンティティID、プロパティ名、現在の状態、以前のようIInterceptorを実装することになった何how-do-i-implement-changetime-and-changeuser-columns-using-nhibernate
状態、変更のタイプ(挿入、更新、削除)、および変更が発生した日時。
次に、私が監査したい各クラスを識別できるように空のインターフェイス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>
を使用しているNHibernateのマッピングでは、これらの特性の各々を実装する一般的なPOCOクラスです。
IInterceptorの実装は(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
私には同じトランザクションの一部である必要があります。そのため、UnitOfWork.Start(UnitOfWorkNestingOptions。CreateNewOrNestUnitOfWork)を使用して、現在のUOWに参加します。私はこの分野で問題を抱えていたことが分かりました。 UOWの一部としてCreateNewOrNestUnitOfWorkオプションを使用すると、その違いが生じました。 –