我有 x ,其中 objectX 类型的对象具有 ListOfObjectYs 属性
List<objectY>
nhibernate映射如下所示:
public ObjectXMap()
{
HasMany(x => x.ListOfObjectYs).AsBag().Inverse();
}
当我去保存它时,我在 objectX 上更改了一些属性,然后有:
Session.SaveOrUpdate(x);
现在我需要更新这个列表的属性。我得到一个新的objectYs列表,我想用一个新列表替换现有的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();
我的问题是:
是否有更好的方法来执行此更新,我需要更新对象(属性),但也更新列表中存在全新列表的属性(意味着需要删除和添加项目)。
答案 0 :(得分:4)
你的问题的答案是否定的。如果要替换列表,则应清除它并添加新项目。如果您将cascade设置为all-delete-orphan,就像在James Kovacs的回答中那样,那么当刷新会话时,对集合的更改将保持不变。
了解NHibernate中Save,Update和SaveOrUpdate的含义非常重要:
另见Manipulating Persistent Data。
假设所有对象都在同一个会话中加载,那么替换一个集合可能很简单:
x.ListOfObjectYs.Clear();
foreach (ObjectY y in newObjectYList)
{
x.ListOfObjectYs.Add(y);
}
_session.Flush();
答案 1 :(得分: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一起保留。