我有兩個相關的對象: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