我有两个相关的对象:ProgramSession和ProgramTask,具有一对多的关系。一个ProgramSession有许多ProgramTasks。所以物体看起来是这样的:NHibernate:父列表属性和相关的子属性不同步
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" />
的问题当我尝试更改ProgramTask的ProgramSession时开始。
如果我从旧会话的ProgramSession.ProgramTasks列表属性中删除ProgramTask,然后将其添加到新会话的相同属性,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
这是在代码在被执行以后,它假定集合与ProgramSession属性同步的ProgramTasks更成问题。例如:
foreach(var programTask in programSession.ProgramTasks)
{
// whatever
}
我用来解决这个问题的一个窍门是查询列表。我不能在任何地方使用它,它显然是一个坏的解决方案,但它强调了这个问题:
var tasksActuallyInSession =
programSession.ProgramTasks
.Where(task => task.ProgramSession == programSession)
.ToList();
有什么办法来处理这种情况?最佳做法?难道我做错了什么?映射不正确?是否有一些我需要设置的超级秘密NHibernate标志?
我相信你的意思是把这些属性放在你在问题中定义的类中。 – tolism7 2009-11-27 14:43:24
你说得对。感谢您的高举。 – shovavnik 2009-11-27 15:03:42