C# .NET将类型转换为子类型
我们在我们的项目中使用NHibernate,我们连接到预更新/插入/删除事件来进行一些审计 我们希望通过审计操作(如更新、插入等)将每个实体审计到其自己的审计表中,该审计表与源表具有相同的模式 我已经研究过自动生成触发器的unaddins,但是当您更改主表时,它似乎会删除并重新创建审计表,我们无法接受这一点,我们还需要一些自定义逻辑,这样我们只会在某些情况下审核记录的实际属性,我们关心的属性是所有对象基类的一部分 为了做到这一点,我想我可以扩展现有的域类,然后为这些扩展类定义一个新的Nhibernate映射 例如: 我们有一个班级乐器C# .NET将类型转换为子类型,c#,nhibernate,auditing,C#,Nhibernate,Auditing,我们在我们的项目中使用NHibernate,我们连接到预更新/插入/删除事件来进行一些审计 我们希望通过审计操作(如更新、插入等)将每个实体审计到其自己的审计表中,该审计表与源表具有相同的模式 我已经研究过自动生成触发器的unaddins,但是当您更改主表时,它似乎会删除并重新创建审计表,我们无法接受这一点,我们还需要一些自定义逻辑,这样我们只会在某些情况下审核记录的实际属性,我们关心的属性是所有对象基类的一部分 为了做到这一点,我想我可以扩展现有的域类,然后为这些扩展类定义一个新的Nhiber
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);
}
它没有额外的功能,它基本上是一个黑客让我们映射到我们的审计表在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);
}
}
实体是作为一个对象给我的
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保存
不幸的是,你似乎不能强制转换为一个变量,它必须是一个实际的类型,这样我就可以将对象强制转换或转换为它的审计类型,而不必为每个接受其基类型并保存属性的审计类型放置构造函数/转换器?好吧,简单的答案是,如果您的auditObject不是InstrumentAudit实例或子类,则不能执行此操作 仅仅因为在Instrument和InstrumentAudit类之间没有额外的字段或方法,并不意味着您可以轻松地在InstrumentAudit之间进行强制转换,因为Instrument不是InstrumentAudit的子类 如果您想在不实现x转换器的情况下克隆对象,请查看@expression trees:您可以设置一个函数字典,按相应的审核类型编制索引,用于存储克隆函数。。。如果您在dict中找到所需类型的克隆函数,请使用它。。。如果没有,请使用表达式树创建一个表达式树,并将其存储以供以后使用
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);
}
}
}