Как сделать свойство NHibernate всегда грязным при использовании динамического обновления или вставки?

Я ищу помощь по проблеме с NHibernate, которая меня давно беспокоила. Короче:

Я ищу способ "сбрасывать" свойство объекта в кеше первого уровня каждый раз, когда я делаю обновление или вставку.

Я хочу добиться того, чтобы рассматриваемое свойство всегда считалось грязным в NHibernate при использовании динамического обновления или вставки.

Предыстория этого состоит в том, что я знаю, что, если транзакция была успешной, столбец, который я хочу "сбросить", будет установлен равным Null в базе данных триггером. С другой стороны, кэш первого уровня не знает этого, и поэтому NHibernate будет думать, что свойство не было обновлено, когда я установил его в то же значение, что и в предыдущем обновлении / вставке. Подвох в том, что мой триггер зависит от того, какое значение установлено. В результате получается, что если я хочу использовать динамическое обновление или вставку, я могу обновлять / вставлять сущность только один раз, не обновляя ее впоследствии (что я действительно не хочу делать).

Советы или помощь будет высоко ценится, потому что я действительно ударил стену здесь

1 ответ

Решение

NHibernate предоставляет много мест для расширения. Среди них сессия IInterceptor, Есть документация с большим количеством деталей:

http://nhibernate.info/doc/nh/en/index.html

В этом случае мы можем создать наш собственный объект, который будет отслеживать нашу сущность (например, клиент) и свойство, которое должно обновляться каждый раз (например, код). Таким образом, наша реализация может выглядеть так:

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

И это все. Хотя Клиент помечен как динамическое обновление, свойство Код всегда будет установлено как грязное

<class name="Client" dynamic-update="true" ...
Другие вопросы по тегам