0

我们在我们的项目中使用 NHibernate,并且我们正在挂钩预更新/插入/删除事件以进行一些审核。

我们希望将每个实体审计到其自己的审计表,该表与源表具有相同的架构(可能使用“更新”、“插入”等审计操作)。

我已经查看了会自动生成触发器的 unHAdins,但是当您对我们无法接受的主表进行更改时,它似乎会删除并重新创建审计表,我们还需要一些自定义逻辑,以便我们只会审计在某些情况下记录它的实际属性(我们关心的属性是我们所有对象的基类的一部分)。

为此,我想我可以扩展我们现有的域类,然后为这些扩展类定义一个新的 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 中的审计表的 hack。

所以这似乎可以工作,但问题实际上是在尝试处理 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保存。

不幸的是,您似乎无法将其转换为必须是实际类型的变量,无论如何我都可以将对象转换或转换为其“审核”类型,而无需为每个审核放置构造函数/转换器采用其基本类型并保存属性的类型?

4

1 回答 1

0

well, the easy answer is, you can't if your auditObject is no instance of InstrumentAudit or a subclass

just because there are no additional fields or methods between the Instrument and InstrumentAudit classes, it doesn't mean you can easily cast from Instrument to InstrumentAudit because Instrument is no subclass of InstrumentAudit

if you want a way to clone your objects without implementing x converters, have a look @ expression trees: you could setup a dictionary of functions, indexed by the corresponding audit types, that stores "clone" functions ... if you find a clone function for the needed type in the dict, use it ... if not, create one using expression trees, and store it for later use

于 2011-05-10T01:42:07.593 回答