具有冗余审计列的NHibernate表每继承

时间:2014-11-26 02:37:05

标签: inheritance nhibernate fluent-nhibernate

我有一堆表与通常的审计列(Created,CreatedBy,Updated,UpdatedBy)。在某些情况下,我有基表和派生表具有相同的列。不幸的是,我对此几乎没有任何治理。

在我的派生类中,我在审计属性上有new

我有一个实现IPreInsertEventListenerIPreUpdateEventListener的类。我正在使用它来设置审计字段,这似乎适用于使用继承的对象。但是,对于那些使用继承的人,审计列不会写入数据库。

以下是我的课程:

public abstract class Base : IAuditable
{
    /* some other properties */

    public virtual DateTime Created { get; set; }
    public virtual string CreatedBy { get; set; }
    public virtual DateTime? Updated { get; set; }
    public virtual string UpdatedBy { get; set; }
    public virtual string UpdateNote { get; set; }
}

public class Derived1 : Base
{
    /* some other properties unique to Derived1*/

    public virtual new DateTime Created { get; set; }
    public virtual new string CreatedBy { get; set; }
    public virtual new DateTime? Updated { get; set; }
    public virtual new string UpdatedBy { get; set; }
    public virtual new string UpdateNote { get; set; }
}    

public class Derived2 : Base
{
    /* some other properties unique to Derived2*/

    public virtual new DateTime Created { get; set; }
    public virtual new string CreatedBy { get; set; }
    public virtual new DateTime? Updated { get; set; }
    public virtual new string UpdatedBy { get; set; }
    public virtual new string UpdateNote { get; set; }
}

以下是我的映射:

public class BaseMap : ClassMap<Base>
{
    public BaseMap()
    {
        //Polymorphism.Explicit();
        Schema("dbo");
        Table("Base");

        Id(x => x.Id)
          .Column("Id")
          .GeneratedBy.Identity();

        #region Created / Updated

        Map(x => x.Created)
            .Column("Created")
            .Not.Nullable();

        Map(x => x.CreatedBy)
            .Column("CreatedBy")
            .Not.Nullable();

        Map(x => x.Updated)
            .Column("Updated");

        Map(x => x.UpdatedBy)
            .Column("UpdatedBy");

        Map(x => x.UpdateNote)
            .Column("UpdateNote");

        #endregion
    }
}

public class Derived1Map : SubclassMap<Derived1>
{
    public Derived1()
    {
        Schema("dbo");
        Table("Derived1");            
        KeyColumn("Id");

        Map(x => x.Created)
            .Column("Created")
            .Not.Nullable();

        Map(x => x.CreatedBy)
            .Column("CreatedBy")
            .Not.Nullable();

        Map(x => x.Updated)
            .Column("Updated");

        Map(x => x.UpdatedBy)
            .Column("UpdatedBy");

        Map(x => x.UpdateNote)
            .Column("UpdateNote");
    }
}

public class Derived2Map : SubclassMap<Derived2>
{
    public Derived2()
    {
        Schema("dbo");
        Table("Derived2");            
        KeyColumn("Id");

        Map(x => x.Created)
            .Column("Created")
            .Not.Nullable();

        Map(x => x.CreatedBy)
            .Column("CreatedBy")
            .Not.Nullable();

        Map(x => x.Updated)
            .Column("Updated");

        Map(x => x.UpdatedBy)
            .Column("UpdatedBy");

        Map(x => x.UpdateNote)
            .Column("UpdateNote");
    }
}

以下是我将监听器附加到NHibernate的方法:

.ExposeConfiguration(c =>
{
    var auditor = new AuditEventListener();
    c.AppendListeners(ListenerType.PreInsert, new IPreInsertEventListener[] { auditor });
    c.AppendListeners(ListenerType.PreUpdate, new IPreUpdateEventListener[] { auditor });       
})

这是听众:

public class AuditEventListener : IPreInsertEventListener, IPreUpdateEventListener
{
    public bool OnPreInsert(PreInsertEvent @event)
    {
        var auditable = @event.Entity as IAuditable;

        var time = DateTime.Now;
        var name = Context.GetUsername();

        Set(x => auditable.Created, @event.Persister, auditable, @event.State, time);
        Set(x => auditable.CreatedBy, @event.Persister, auditable, @event.State, name);

        return false;
    }

    public bool OnPreUpdate(PreUpdateEvent @event)
    {
        var auditable = @event.Entity as IAuditable;
        var persister = @event.Persister;

        var dirties = persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session);

        var dirtyPropNames = dirties.Select(dirty => persister.PropertyNames[dirty]).ToList();

        var time = DateTime.Now;
        var name = Context.GetUsername();
        var note = "Updated " + string.Join(",", dirtyPropNames);

        Set(x => auditable.Updated, persister, auditable, @event.State, time);
        Set(x => auditable.UpdatedBy, persister, auditable, @event.State, name);
        Set(x => auditable.UpdateNote, persister, auditable, @event.State, note);

        return false;
    }

    private void Set<T, U>(Expression<Func<U, T>> expression, IEntityPersister persister, U instance, object[] state, T value)
    {
        var member = expression.Body as MemberExpression;
        if (member != null)
        {

            var index = Array.IndexOf(persister.PropertyNames, member.Member.Name);
            if (index == -1)
            {
                return;
            }
            state[index] = value;

            var property = (member.Member as PropertyInfo);
            if (property != null)
            {
                property.SetValue(instance, value, null);
            }
        }
    }
}

0 个答案:

没有答案