在使用动态更新或插入时,如何使NHibernate认为属性总是变脏?

时间:2012-11-19 12:14:21

标签: c# nhibernate nhibernate-mapping nhibernate-caches

我正在寻找有关NHibernate问题的帮助,这一直困扰着我一段时间。长话短说:

  

我正在寻找一种方法,在第一级缓存中,每次执行更新或插入时,“重置”实体上的属性。

     

我想要实现的是,当使用动态更新或插入时,NHibernate将始终认为有问题的属性是脏的。

这个背景故事是我知道,如果事务成功,我想要“重置”的列将通过触发器在数据库中设置为Null。另一方面,第一级缓存不知道这一点,因此当我将其设置为与之前更新/插入时相同的值时,NHibernate会认为该属性未更新。问题是我的触发器依赖于设置的值。由此产生的混乱是,如果我想使用动态更新或插入,我只能更新/插入实体一次而不“事后”刷新它(我真的不想这样做)。

提示或帮助将非常感激,因为我真的在这里碰壁

1 个答案:

答案 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" ...