2010-12-10 25 views
6

我有X該類型的對象_對象具有財產ListOfObjectYs那是一個在NHibernate中,無法更新子對象的列表

List<objectY> 

NHibernate的映射如下所示:

public ObjectXMap() 
    { 
     HasMany(x => x.ListOfObjectYs).AsBag().Inverse(); 
    } 

,當我去保存它,我改變_對象,然後有一些屬性:

Session.SaveOrUpdate(x); 

現在我需要更新這個屬性是一個列表。我得到一個新的objectY列表,我想用新列表替換現有的objectY列表。我需要這樣做嗎?

foreach (ObjectY y in x.ListOfObjectYs) 
       { 
        Session.Delete(y); 
        deleted = true; 
       } 
       if (deleted) 
       { 
        _session.Flush(); 
       } 
       x.ListOfObjectYs.Clear(); 

       foreach (ObjectY y in newObjectYList) 
       { 
        x.ListOfObjectYs.Add(y); 
        Session.SaveOrUpdate(y); 
       } 
       _session.Flush(); 

我的問題是:

  1. 我是否有添加新的之前刪除一切,齊平。
  2. 做我需要做的所有這些增量的
  3. 之間

有沒有這樣做更新的更好的方法,我需要在有更新的對象(屬性),而且更新的列表屬性保存一個全新的列表(意味着需要刪除和添加項目)。

回答

3

您的問題的答案是否定的。如果你想替換列表,你應該清除它並添加新的項目。如果您將cascade設置爲all-delete-orphan,如James Kovacs的答案中所述,那麼在刷新會話時,集合的更改將會保留。

明白了什麼保存,更新,並SaveOrUpdate NHibernate的意思是很重要的:

  • 保存 - 創建一個新的對象持久
  • 更新 - 做出改變的分離對象持久
  • SaveOrUpdate - 保存或根據對象標識符的未保存值更新

另請參閱Manipulating Persistent Data

假設所有的對象都在同一個會議上加載然後更換一個集合可能是一樣簡單:

x.ListOfObjectYs.Clear(); 
foreach (ObjectY y in newObjectYList) 
{ 
    x.ListOfObjectYs.Add(y); 
} 
_session.Flush(); 
3

您需要HasMany()上的級聯。如果子對象完全由父級擁有,則Cascade.AllDeleteOrphan()是一個不錯的選擇。通過這種方式,保存,更新和刪除父級會自動級聯到子對象,從而不需要複雜的foreach塊。有了這個,只需更新您的收藏並進行交易。 NHibernate將負責其餘部分。

更新:要修改列表,只需像往常一樣使用.NET集合添加和刪除列表中的項目即可。例如:

public void RemoveY(ObjectY someY) { 
    ListOfObjectYs.Remove(someY); 
} 

public void AddY(ObjectY someY) { 
    ListOfObjectYs.Add(someY); 
} 

public void ClearAllY() { 
    ListOfObjectYs.Clear(); 
} 

當事務被提交時,對ListOfObjectYs集合的任何更改都將與父ObjectX一起保持。

+0

要清楚,我加Cascade.AllDeleteOrphan()我的映射文件。這就夠了。你能否提供語法來更新列表,因爲我不完全遵循你的意思,「我可以刪除它們」,在某些時候我必須刪除現有的條目並添加新的條目。我沒有看到我如何擺脫這一點。 – leora 2010-12-10 03:25:50

+0

- 我現在得到一個錯誤:具有cascade =「all-delete-orphan」的集合不再被擁有實體實例引用:ObjectY – leora 2010-12-10 03:52:04