У меня есть два связанных объекта: ProgramSession и ProgramTask, с отношением один ко многим. ProgramSession имеет много программных задач. Итак, объекты выглядят так:
public class ProgramSession
{
public virtual IList<ProgramTask> ProgramTasks
{
get { return _programTasks; }
set { _programTasks = value; }
}
}
public class ProgramTask
{
public virtual ProgramSession ProgramSession
{
get { return _programSession; }
set { _programSession = value; }
}
}
И сопоставления ...
ProgramSession.hbm.xml
<bag name="ProgramTasks" lazy="false" cascade="all-delete-orphan" inverse="true" >
<key column="SessionUid"></key>
<one-to-many class="ProgramTask"></one-to-many>
</bag>
ProgramTask.hbm.xml
<many-to-one name="ProgramSession" column="SessionUid" class="ProgramSession" />
Проблемы начинаются, когда я пытаюсь изменить ProgramSession для ProgramTask.
Если я удалю ProgramTask из свойства списка ProgramSession.ProgramTasks старого сеанса, а затем добавлю его к тому же свойству в новом сеансе, NHibernate сообщит мне, что удаленный объект будет восстановлен.
Если я просто изменю значение объекта ProgramTask.ProgramSession, у меня не возникнет проблем с сохранением. Однако я получаю странное поведение, если не сохраняю сразу, потому что свойства ProgramSession.ProgramTasks (в обоих сеансах) не синхронизируются до тех пор, пока не обновится сеанс NHibernate.
Изменение объекта ProgramTask.ProgramSession без непосредственного изменения списков также создает недопустимое состояние. Возьмите следующий код в качестве примера:
programTask.ProgramSession = newProgramSession;
Assert.That(newProgramSession.ProgramTasks.Contains(programTask)); // fails
Assert.That(!oldProgramSession.ProgramTasks.Contains(programTask)); // fails
Это более проблематично в коде, который выполняется позже, при котором предполагается, что коллекции ProgramTasks синхронизируются со свойством ProgramSession. Например:
foreach(var programTask in programSession.ProgramTasks)
{
// whatever
}
Один из способов, который я использовал для обхода этого, был запрос к списку. Я не могу использовать его везде, и это явно плохое решение, но оно подчеркивает проблему:
var tasksActuallyInSession =
programSession.ProgramTasks
.Where(task => task.ProgramSession == programSession)
.ToList();
Есть ли способ справиться с такой ситуацией? Лучшая практика? Я делаю что-то неправильно? Является ли отображение неверным? Есть ли какой-то сверхсекретный флаг NHibernate, который мне нужно установить?