私のアプリケーションでは、フィールド レベルの変更追跡を行う必要があるいくつかの異なる種類のエンティティがあります。私はこれをグーグルで検索しましたが、すでに永続化されているエンティティのフィールドを変更するだけで、単純な「挿入日」および「更新日」監査追跡を行う例しか思いつきません。次の理由により、私の要件はより複雑です。
- 保存されているエンティティのフィールドを変更するだけでなく、変更を表す新しいエンティティを作成する必要があります (私が見つけた挿入日、更新日の例のように)
- 追跡されたエンティティを更新する同じトランザクションで、これらの新しいエンティティを DB に保存する必要があります
- 追跡対象のエンティティに添付された ValueObjects のコレクションへの変更を追跡する必要があります
- 追跡対象のエンティティごとに個別のログ コードを記述する必要はありません。
コード例:
public interface ITrackChanges {}
{
}
public class Account : ITrackChanges
{
public int Id;
public string AccountNumber;
public string CustomerName;
public string CustomerAddress;
}
public class Computer : ITrackChanges
{
public int Id;
public string AssetTag;
public string SerialNumber;
public IEnumerable<IPAddress> IPAddresses;
}
public class IPAddress : ValueObject
{
public string Address;
}
Account オブジェクトまたは Computer オブジェクトのいずれかの値が変更されるか、Computer オブジェクトに関連付けられた IPAddresses のリストが変更されるたびに、次のエンティティ変更レコードを作成して保存する必要があります。
public class EntityChange
{
public string EntityType;
public string EntityId;
public string PropertyName;
public string OldValue;
public string NewValue;
}
追跡対象の各エンティティは ITrackChanges マーカー インターフェイスを実装し、各値オブジェクトは ValueObject 基本クラスから継承します。値オブジェクトは、NHibernate のコンポーネントとしてマップされます。
最終結果として取得しようとしているものの例として、Computer オブジェクトを ID 1 で更新し、AssetTag を "ABC123" から "ABC124" に変更し、IP アドレスのリストを { "1.2.3.4" から変更するとします。 " } を { "1.2.3.4" , "1.2.3.5" } に変更すると、2 つの EntityChange レコードを取得する必要があります。
EntityChange #1
{
EntityType = "Computer"
EntityId = 1
PropertyName = "AssetTag"
OldValue = "ABC123"
NewValue = "ABC124"
}
EntityChange #2
{
EntityType = "Computer"
EntityId = 1
PropertyName = "IPAddresses"
OldValue = "1.2.3.4"
NewValue = "1.2.3.4, 1.2.3.5"
}
これを実装するための最良の方法に関するアイデアはありますか? ドキュメントを読んだところ、インターセプターやイベントリスナーを作成する必要があるように見えますが、更新中のエンティティを変更するだけの例を見つけることができませんでした。サンプルコードは、どんな回答でも大歓迎です。
これが NHibernate でサポートされているものであると仮定するのは間違っていますか? ORM として LLBLGen を使用する以前のアプリケーションでこれを実装できましたが、NHibernate を使用するアプリケーションでこれを実装しなければならなかったのはこれが初めてです。