如何检测NHibernate中的集合更改

时间:2011-06-29 14:47:03

标签: nhibernate collections

如何在NHibernate中检测多个集合和列表中的更改(添加和删除)?

我正在使用拦截器来检测对象模型中的更改(用于审计等),这适用于对象内的更改(使用OnSave / OnFlushDirty),但不适用于集合。

当集合更改时,会调用OnCollectionUpdate方法,但它只接收持有集合的对象的密钥和集合的最新项。

我需要的是:

  1. 持有集合的对象(或者至少是类型+键,键只在我的系统中的一个类中是唯一的)我现在只有键。

  2. 集合的属性名称(我有多个集合的类)

  3. 已添加项目的列表和已删除项目的列表(或者,当前事务之前和之后的集合内容)。

  4. 有没有办法获取这些信息?

4 个答案:

答案 0 :(得分:1)

我目前正在研究这个问题。我自己还没有想出你的第三个问题(我试图找出答案),但是这应该可以帮助你实现#1和#2:

public static void SomeMethod(this ISession session, object entity)
{            
    //this will give you the information about your entity
    String className = NHibernateProxyHelper.GuessClass(entity).FullName;
    ISessionImplementor sessionImpl = session.GetSessionImplementation();
    IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

    //at this point you can use the persister object to retrieve the info you need:

    //this gives you all properties and their values
    Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);

    //this will return the types:
    IType[] typeArray = persister.PropertyTypes;

    //each IType object has a IsCollectionType bool which tells you if it is a collection:
    bool isCollection = IType[0].IsCollectionType;
}

答案 1 :(得分:1)

如果你没有覆盖标准的nhibernate集合(list,set,map),你总是可以得到集合的初始内容(在任何变化之前保存在base中的内容)。列表示例:

PersistentList c = myCollection as PersistentList;
if ((c == null)||(!c.IsDirty)) {
        return;
}
IEnumerable storedCollection = c.StoredSnapshot as IEnumerable;
if ((storedCollection == null)) {
        return; //looks like a error
}
foreach(var element in storedCollection) {
     //do something with old items
}
foreach(var element in storedCollection) {
     //do something with new items
}

当然,您可以确定哪些元素已添加,删除或保持不变。

答案 2 :(得分:0)

可能有点棘手,但是创建自定义代理呢?

答案 3 :(得分:0)

这是不是 NHibernate代码(它是Hibernate Java代码),但谷歌搜索NHibernate API使它看起来像类似的代码可以让你开始NHibernate(有一个{{1}具有PersistentMap属性和Owner属性)的类:

CollectionSnapshot

请注意,我知道这不是C#或NHibernate代码。如果这对NHibernate完全没用,请评论(如果API并非完全相似,即使我的谷歌搜索说它类似),我也会删除帖子。

我现在沉浸在Java土地上,或者我会为你试试这个:)