如何检测NHibernate中的集合更改
如何检测NHibernate中多对多集合和列表的更改(添加和删除) 我正在使用拦截器来检测对象模型中的更改(用于审计等),这对于对象内的更改(使用OnSave/OnFlushDirty)非常有效,但对于集合则不适用 当集合更改时,将调用OnCollectionUpdate方法,但它只接收保存集合的对象的键和集合的最新项 我需要的是:如何检测NHibernate中的集合更改,nhibernate,collections,Nhibernate,Collections,如何检测NHibernate中多对多集合和列表的更改(添加和删除) 我正在使用拦截器来检测对象模型中的更改(用于审计等),这对于对象内的更改(使用OnSave/OnFlushDirty)非常有效,但对于集合则不适用 当集合更改时,将调用OnCollectionUpdate方法,但它只接收保存集合的对象的键和集合的最新项 我需要的是: 持有集合的对象(或者至少是type+key,该键仅在我的系统中的类中是唯一的)我现在只有该键 集合的属性名称(我有多个集合的类) 添加项列表和删除项列表(或者,当前
有什么方法可以获得这些信息吗?可能有点棘手,但是创建一个自定义代理怎么样?我目前正在自己处理这个问题。我自己还没有弄明白你的第三个问题(不过我正在努力找出答案),但这应该能帮助你解决第1和第2个问题: 这不是NHibernate代码(它是Hibernate Java代码),但通过谷歌搜索NHibernate API,看起来类似的代码也可以让您开始使用NHibernate(有一个
PersistentMap
类,它有一个Owner
属性和一个CollectionSnapshot
属性):
public void onCollectionUpdate(对象集合,可序列化id){
System.out.println(“**onCollectionUpdate”);
if(PersistentMap的集合实例){
PersistentMap newValues=(PersistentMap)集合;
对象所有者=newValues!=null?newValues.getOwner():null;
设置oldValues=newValues!=null
((映射)newValues.getStoredSnapshot()).keySet()
:null;
System.out.println(“所有者:”+(所有者!=null?所有者.toString():“(null)”);
System.out.println(“oldValues:”+(oldValues!=null?oldValues.toString():“(null)”);
System.out.println(“newValues:”+(newValues!=null?newValues.toString():“(null)”);
}else if(PersistentSet的集合实例){
PersistentSet newValues=(PersistentSet)集合;
对象所有者=newValues!=null?newValues.getOwner():null;
设置oldValues=newValues!=null
((映射)newValues.getStoredSnapshot()).keySet()
:null;
System.out.println(“所有者:”+(所有者!=null?所有者.toString():“(null)”);
System.out.println(“oldValues:”+(oldValues!=null?oldValues.toString():“(null)”);
System.out.println(“newValues:”+(newValues!=null?newValues.toString():“(null)”);
}
}
请注意,我知道这不是C#或NHibernate代码。如果这对NHibernate完全没有用处(如果API一点都不相似,尽管我的谷歌搜索结果显示它是相似的),请发表评论,我将删除这篇文章
我现在沉浸在Java领域,或者我会为您尝试一下:)如果您不重写standart nhibernate集合(列表、集合、映射),您总是可以获得集合的初始内容(在任何更改之前保存在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
}
当然,您可以确定哪些元素已被添加、删除或保持不变。我真的看不出这对我有什么帮助。例如,如果我们使用博客数据模型,我在检测普通对象属性(仅在集合中)的更改时不会遇到问题,并且集合的Add和Remove方法不会在代理上调用(同样,这在非延迟加载的对象上也不起作用),当有人调用post.Comments.Add时,会在代理上调用getter属性,并且可以被它捕获-但这并没有告诉我调用了Add(据我所知,它可能是来自foreach循环的GetEnumerator)它并没有告诉我添加了什么。为什么不能将快照内容与实际的持久收集内容进行比较?
public void onCollectionUpdate(Object collection, Serializable id) {
System.out.println("****onCollectionUpdate");
if(collection instanceof PersistentMap) {
PersistentMap newValues = (PersistentMap) collection;
Object owner = newValues != null ? newValues.getOwner() : null;
Set<?> oldValues = newValues != null
? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet()
: null;
System.out.println("owner: " + (owner != null ? owner.toString() : "(null)"));
System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)"));
System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)"));
} else if (collection instanceof PersistentSet) {
PersistentSet newValues = (PersistentSet) collection;
Object owner = newValues != null ? newValues.getOwner() : null;
Set<?> oldValues = newValues != null
? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet()
: null;
System.out.println("owner: " + (owner != null ? owner.toString() : "(null)"));
System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)"));
System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)"));
}
}
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
}