我正在寻找有关NHibernate问题的帮助,这一直困扰着我一段时间。长话短说:
我正在寻找一种方法,在第一级缓存中,每次执行更新或插入时,“重置”实体上的属性。
我想要实现的是,当使用动态更新或插入时,NHibernate将始终认为有问题的属性是脏的。
这个背景故事是我知道,如果事务成功,我想要“重置”的列将通过触发器在数据库中设置为Null。另一方面,第一级缓存不知道这一点,因此当我将其设置为与之前更新/插入时相同的值时,NHibernate会认为该属性未更新。问题是我的触发器依赖于设置的值。由此产生的混乱是,如果我想使用动态更新或插入,我只能更新/插入实体一次而不“事后”刷新它(我真的不想这样做)。
提示或帮助将非常感激,因为我真的在这里碰壁
答案 0 :(得分:3)
NHibernate提供了许多扩展的地方。其中包括会话IInterceptor
。有许多细节的文档:
http://nhibernate.info/doc/nh/en/index.html#objectstate-interceptors
在这种情况下,我们可以创建自定义的一个,它将观察我们的实体(例如客户端)和每次都必须更新的属性(例如代码)。所以我们的实现可能如下所示:
public class MyInterceptor : EmptyInterceptor
{
public override int[] FindDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types)
{
var result = new List<int>();
// we do not care about other entities here
if(!(entity is Client))
{
return null;
}
var length = propertyNames.Length;
// iterate all properties
for(var i = 0; i < length; i++)
{
var areEqual = currentState[i].Equals(previousState[i]);
var isResettingProperty = propertyNames[i] == "Code";
if (!areEqual || isResettingProperty)
{
result.Add(i); // the index of "Code" property will be added always
}
}
return result.ToArray();
}
}
注意:这只是一个例子!应用您自己的逻辑来检查脏属性。
我们必须以这种方式包裹Session
:
var interceptor = new MyInterceptor()
_configuration.SetInterceptor(interceptor);
就是这样。虽然客户端被标记为动态更新,但代码属性将始终设置为 dirty
<class name="Client" dynamic-update="true" ...