如何从NHibernate中的审计事件侦听器中获取数据库列名称 [英] How do you get the database column name out of an auditing event listener in NHibernate

查看:318
本文介绍了如何从NHibernate中的审计事件侦听器中获取数据库列名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

$

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

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

public virtual string FirstNames {get;组; }

public virtual string Surname {get;组; }
}

我的映射器如下:

  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)
{
}
}

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



正如您所看到的,我可以访问表名,和主键字段...但是找不到其他属性。

解决方案

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



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

  public interface IMappingDescription 
{
string PropertyName {get; }
string ColumnName {get; }
bool CanInsert {get; }
bool CanUpdate {get; }
类型PropertyType {get; }
bool IsLocalDateTime {get; }
}

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

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

if(persister == null)
{
throw new InvalidCastException(NHibernate ISessionFactory没有在GetClassMetadata()上返回AbstractEntityPersister);
}

//属性集
var propertyNameList = persister.PropertyNames;

//结果
var map = new List< MappingDescription>();

//这里我们注入ID属性的映射(每个ID除去一列)
map.Add(new MappingDescription
{
PropertyName = Constants.Common。 ID,
ColumnName = persister.KeyColumnNames.First(),
PropertyInfo = entityType.GetProperty(Constants.Common.ID),
});

//这里我们得到剩余映射属性的所有设置
foreach(propertyNameList中的var propertyName)
{
var index = persister.GetPropertyIndex(propertyName);

//检查如何区分我们是否在UTC或本地工作
var isLocal = persister.GetPropertyType(propertyName)is NHibernate.Type.LocalDateTimeType
|| persister.GetPropertyType(propertyName)是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;
}


I'm attempting to audit/log the table and field names with their modified value.

My DTO is named differently to the database:

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

    public virtual string FirstNames { get; set; }

    public virtual string Surname { get; set; }
}

My mapper is as follows:

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();

As you can see - the database field names are different to the mapped objects names.

I don't care whether I grab out the column names pre or post insert. I have been looking in the event objects for a while and can't find them.

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)
    {
    }
}

Can someone please give me a way to grab the database column names, and if it's possible to map them to the actual values being inserted/updated?

As you can see, I do have access to the table name, and primary key field... But can't find the other properties.

解决方案

This is my way how to ask NHibernate to get all the information. In my case all the settings like column name, can Insert, can Update... are already there, and they could/should be used (even if only for documentation). So, the simplified, but fully working code snippets are below...

Firstly let's create some description object MappingDescription: , into which we will move all the settings and return it as a IList

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

And the static method, for any mapped persistent class 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;
}

这篇关于如何从NHibernate中的审计事件侦听器中获取数据库列名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆