У меня есть старое приложение WinForms 4.x, которое использует Castle.ActiveRecord 3.0.0 RC (который, я думаю, является последней доступной версией) поверх NHibernate 3.1.0.4000 (который не является последним, но он был актуален вв то время).
Я заметил странное поведение несоответствия данных внутри одной формы.Он создает TransactionScope
для срока жизни формы и не фиксирует его до конца.Он выбирает список объектов и предоставляет для них некоторый пользовательский интерфейс редактирования.Одним из них является флажок для логического свойства IsPrimary
.
Предполагается, что только один объект имеет IsPrimary
== true, поэтому при установке флажка он имеет значение:
var others = MyData.FindAllByProperty("IsPrimary", true)
.Where(x => x.Name != current.Name).ToList();
foreach (var data in others)
{
data.IsPrimary = false;
data.Save();
}
current.IsPrimary = true;
current.Save();
(что, вероятно, можно было бы сделать более эффективно, но пока игнорируйте это. current
- это объект, у которого установлен флажок. И все они имеют уникальные имена.)
Это работает корректно в большинстве случаев.время, но если вы откроете окно, поставьте галочку на каком-то другом элементе (чтобы он делал выше и правильно установил предыдущий на false), а затем, не закрывая окно, попытаетесь снова поставить галочку на первом элементе, вы завершаетес двумя установленными объектами IsPrimary
.
Проблема заключается в том, что FindAllByProperty
возвращает исходное состояние объекта вне транзакции формы, игнорируя любые изменения.
Если я заменювызов с этим кодом:
var others = MyData.FindAll().Where(x => x.IsPrimary)
.Where(x => x.Name != current.Name).ToList();
Затем он возвращает правильный результат (включая изменения, внесенные в транзакции формы).
Это известная ошибка?Есть ли обходной путь, отличный от использования FindAll()
?
Редактировать : FWIW, использование явных критериев дает тот же результат (он возвращает устаревшие данные, а не правильные данные):
var criteria = DetachedCriteria.For(typeof(MyData))
.SetResultTransformer(CriteriaSpecification.DistinctRootEntity)
.Add(Restrictions.Eq("IsPrimary", true))
.Add(Restrictions.Not(Restrictions.IdEq(current.Id)));
var others = MyData.FindAll(criteria);
// still stale