4

しばらくの間私を悩ませてきたNHibernateの問題について助けを求めています。短編小説:

更新または挿入を行うたびに、第1レベルのキャッシュでエンティティのプロパティを「リセット」する方法を探しています。

私が達成したいのは、動的更新または挿入を使用する場合、問題のプロパティはNHibernateによって常にダーティであると見なされることです。

これの裏話は、トランザクションが成功した場合、「リセット」したい列がトリガーによってデータベースでNullに設定されることを知っていることです。反対に、第1レベルのキャッシュはこれを認識しないため、NHibernateは、前回の更新/挿入で行ったのと同じ値に設定したときに、プロパティが更新されなかったと見なします。キャッチは、私のトリガーが設定されているこの値に依存していることです。結果として生じる混乱は、動的更新または挿入を使用したい場合、後でエンティティを「更新」せずにエンティティを更新/挿入できるのは1回だけであるということです(これは本当にやりたくないです)。

私は本当にここで壁にぶつかったので、ヒントや助けをいただければ幸いです

4

1 に答える 1

3

Hibernate は拡張のための多くの場所を提供します。その中には Session がありIInterceptorます。多くの詳細が記載されたドキュメントがあります。

http://nhibernate.info/doc/nh/en/index.html#objectstate-interceptors

この場合、エンティティ (例: Client ) と毎回更新する必要があるプロパティ (例: Code ) を監視するカスタム エンティティを作成できます。したがって、実装は次のようになります。

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

で、これです。クライアントが動的更新としてマークされている間、プロパティCodeは常にダーティとして設定されます

<class name="Client" dynamic-update="true" ...
于 2012-11-19T17:07:43.643 に答える