我们正在项目中使用NHibernate,我们正在进行预更新/插入/删除事件以进行一些审核。
我们希望将每个实体审核到自己的审核表,该审核表与源表具有相同的模式(可能具有审核操作,如“更新”,“插入”等)。
我已经查看了会自动生成触发器的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);
}
}
}
上面是我想要工作的代码,基本上我知道对象是应该被审计的对象,它是我的基础对象之一,所以我想将它转换为审计对象的子类型并传递它是nhibernate来保存。
不幸的是,似乎你不能转换为变量它必须是一个实际的类型,无论如何都在这周围所以我可以将对象转换或转换为它的“审计”类型而不必放置构造函数/转换器对于采用其基本类型并保存属性的每种审计类型?
答案 0 :(得分:0)
嗯,简单的答案是,如果您的auditObject不是InstrumentAudit或子类的实例,则不能这样做
因为Instrument和InstrumentAudit类之间没有其他字段或方法,这并不意味着您可以轻松地从Instrument转换为InstrumentAudit,因为Instrument不是InstrumentAudit的子类
如果你想要一种克隆你的对象而不实现x转换器的方法,看看@表树:你可以设置一个函数字典,由相应的审计类型索引,存储“克隆”函数...如果你在dict中找到所需类型的克隆函数,使用它...如果没有,使用表达式树创建一个,并存储以供以后使用