C# .NET将类型转换为子类型

C# .NET将类型转换为子类型,c#,nhibernate,auditing,C#,Nhibernate,Auditing,我们在我们的项目中使用NHibernate,我们连接到预更新/插入/删除事件来进行一些审计 我们希望通过审计操作(如更新、插入等)将每个实体审计到其自己的审计表中,该审计表与源表具有相同的模式 我已经研究过自动生成触发器的unaddins,但是当您更改主表时,它似乎会删除并重新创建审计表,我们无法接受这一点,我们还需要一些自定义逻辑,这样我们只会在某些情况下审核记录的实际属性,我们关心的属性是所有对象基类的一部分 为了做到这一点,我想我可以扩展现有的域类,然后为这些扩展类定义一个新的Nhiber

我们在我们的项目中使用NHibernate,我们连接到预更新/插入/删除事件来进行一些审计

我们希望通过审计操作(如更新、插入等)将每个实体审计到其自己的审计表中,该审计表与源表具有相同的模式

我已经研究过自动生成触发器的unaddins,但是当您更改主表时,它似乎会删除并重新创建审计表,我们无法接受这一点,我们还需要一些自定义逻辑,这样我们只会在某些情况下审核记录的实际属性,我们关心的属性是所有对象基类的一部分

为了做到这一点,我想我可以扩展现有的域类,然后为这些扩展类定义一个新的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);
        }
它没有额外的功能,它基本上是一个黑客让我们映射到我们的审计表在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);
            }
        }
    }