如何从NHibernate中的审计事件侦听器中获取数据库列名

时间:2014-06-11 01:25:43

标签: database nhibernate event-listener

我尝试使用修改后的值审核/记录表名和字段名称。

我的DTO与数据库的命名方式不同:

public class Emp
{
    public virtual int EmployeeNo { get; set; }

    public virtual string FirstNames { get; set; }

    public virtual string Surname { get; set; }
}

我的映射器如下:

var mapper = new ModelMapper();

mapper.Class<Emp>(rc =>
{
    rc.Table("EMP");
    rc.Id(x => x.EmployeeNo, m => m.Column("EMPLOYEE_NO"));
    rc.Property(x => x.FirstNames, map => map.Column("FIRST_NAMES"));
    rc.Property(x => x.Surname, map => map.Column("SURNAME"));
});

var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

如您所见 - 数据库字段名称与映射的对象名称不同。

我不在乎是否在插入前或插入后删除列名。我一直在查看事件对象一段时间但无法找到它们。

public class AuditingEventListener : IPreInsertEventListener, IPreUpdateEventListener, IPostUpdateEventListener, IPostInsertEventListener
{
    public AuditingEventListener()
    {
    }

    public bool OnPreInsert(PreInsertEvent eventItem)
    {
        return false;
    }

    public bool OnPreUpdate(PreUpdateEvent eventItem)
    {
        return false;
    }

    public void OnPostUpdate(PostUpdateEvent @event)
    {
    }

    public void OnPostInsert(PostInsertEvent @event)
    {
    }
}

有人可以给我一个方法来获取数据库列名,是否可以将它们映射到插入/更新的实际值?

正如您所看到的,我可以访问表名和主键字段......但无法找到其他属性。 enter image description here

1 个答案:

答案 0 :(得分:0)

这是我如何让NHibernate获取所有信息的方法。在我的情况下,所有的设置,如列名,可以插入,可以更新...已经存在,他们可以/应该使用(即使仅用于文档)。因此,简化但完全正常工作的代码片段低于......

首先让我们创建一些描述对象MappingDescription:,我们将移动所有设置并将其作为IList

返回
public interface IMappingDescription
{
    string PropertyName { get; }
    string ColumnName { get; }
    bool CanInsert { get; }
    bool CanUpdate { get; }
    Type PropertyType { get; }
    bool IsLocalDateTime { get; }
}

静态方法,对于任何映射的持久化类TEntity:

public static IList<MappingDescription> ReadMappingInfo<TEntity>()
{
    var entityType = typeof(TEntity);
    var factory = ... // Get your ISessionFactory
    var persister = factory.GetClassMetadata(entityType) as AbstractEntityPersister;

    if (persister == null)
    {
        throw new InvalidCastException("NHibernate ISessionFactory did not return 'AbstractEntityPersister'  on GetClassMetadata()");
    }

    // the set of Properties
    var propertyNameList = persister.PropertyNames;

    // the result
    var map = new List<MappingDescription>();

    // here we inject the mapping for ID property (execting one column per ID)
    map.Add(new MappingDescription
    {
        PropertyName = Constants.Common.ID,
        ColumnName   = persister.KeyColumnNames.First(),
        PropertyInfo = entityType.GetProperty(Constants.Common.ID),
    });

    // here we get all the settings for remaining mapped properties
    foreach (var propertyName in propertyNameList)
    {
        var index = persister.GetPropertyIndex(propertyName);

        // a check how to distinguish if we do work in UTC or Local
        var isLocal = persister.GetPropertyType(propertyName) is NHibernate.Type.LocalDateTimeType
            || persister.GetPropertyType(propertyName) is NHibernate.Type.TimestampType;

        var description = new MappingDescription
        {
            PropertyName = propertyName,
            ColumnName   = persister.GetPropertyColumnNames(propertyName).First(),
            PropertyInfo = entityType.GetProperty(propertyName),
            CanInsert = persister.PropertyInsertability[index],
            CanUpdate = persister.PropertyUpdateability[index]
                || persister.PropertyTypes[index].IsCollectionType, // <idbag> has Updatebility false 
            IsLocalDateTime = isLocal,
        };

        map.Add(description);
    }
    return map;
}