Как сделать свойство 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" ...