私たちはプロジェクトでNHibernateを使用しており、いくつかの監査を行うためにpre update / insert/deleteイベントにフックしています。
ソーステーブルと同じスキーマを持つ独自の監査テーブルに対して各エンティティを監査する必要があります(「更新」、「挿入」などの監査操作を使用する場合があります)。
トリガーを自動的に生成するunHAddinsを見てきましたが、受け入れることができないメインテーブルに変更を加えると、監査テーブルが削除されて再作成されるようです。また、監査のみを行うようにカスタムロジックを用意する必要があります。実際のプロパティの特定の状況下で記録します(関心のあるプロパティは、すべてのオブジェクトの基本クラスの一部です)。
これを簡単に行うために、既存のドメインクラスを拡張して、それらの拡張クラスの新しいNhibernateマッピングを定義できると考えました。
例えば:
クラス楽器があります
public class Instrument : BaseObject, IAuditable
{
public virtual string Title { get; set; }
public virtual IList<Control> Controls { get; set; }
public virtual CouncilRegion Region { get; set; }
public Type GetAuditType()
{
return typeof (InstrumentAudit);
}
Iauditableオブジェクトの監査クラスがどのクラスであるかを確認できるように、インターフェイスIauditableを定義しました。
監査クラスは以下のとおりです。
public class InstrumentAudit : Instrument
{}
追加機能はありません。基本的には、NHibernateの監査テーブルにマップできるようにするためのハックです。
したがって、これは機能するように見えますが、NHibernateイベントを処理しようとすると実際に問題が発生します
public class EventListener: IPreInsertEventListener, IPreUpdateEventListener, IPreDeleteEventListener
{
private readonly IAuditLogger _logger = new AuditLogger();
public bool OnPreInsert(PreInsertEvent e)
{
Audit(e.Entity as BaseObject, AuditType.Insert);
return false;
}
}
private void Audit(object entity, AuditType auditType)
{
if(entity is IAuditable && entity is BaseObject)
{
_logger.Log(entity, auditType);
}
}
e.Entityはオブジェクトとして私に与えられます。
public class AuditLogger : IAuditLogger
{
public void Log(object entity, AuditType auditType)
{
if (entity is IAuditable && entity is BaseObject)
{
var auditObject = entity as IAuditable;
Type type = auditObject.GetAuditType();
var x = (type) auditObject;
DataRepository.Instance.Save(x);
}
}
}
上記は私が働きたいコードです、基本的に私はオブジェクトが監査されるべきものであり、それが私のベースオブジェクトの1つであることを知っているので、それを監査オブジェクトのサブタイプに変換してnhibernateに渡したいと思います保存する。
残念ながら、実際の型である必要がある変数にキャストできるようには見えません。とにかくこれを回避できるので、監査ごとにコンストラクター/コンバーターを配置しなくても、オブジェクトを「監査」型にキャストまたは変換できます。基本型を取り、プロパティを保存する型?