Backgroud:我正在使用NHibernate作为我的模型层,我有一个HTTP模块负责在每个请求开始时实例化会话并在每个请求结束时清理它(即每个请求的会话)。在这种情况下,我有两种对象类型:
ParentItem - 包含一堆属性和一组ChildItems的对象。
ChildItem - 一个对象,其属性包括DateTime(EffectiveDate)和指向完全不同的数据库的未强制FK。 ChildItem类也包含一个返回父级的引用(多对一)
虽然ParentItem在其集合中有多个ChildItem,但我通常只对集合中最新的ChildItem感兴趣。
欲望:想要一个数据绑定控件(GridView或ListView,我不关心哪个),它允许我从我的数据源添加/编辑/删除ParentItems。我还希望能够设置一个新的“最新”ChildItem作为编辑/更新的一部分。
问题:我似乎无法从OnItemUpdating处理程序中的GridView / ListView访问底层DataItem(这不是意料之外的,因为数据现在位于视图状态中)。我认为我可以做的是使用数据绑定控件中的ID从我的会话加载ParentItem,创建一个新的ChildItem,将其添加到ParentItem,然后保存ParentItem。由于NHibernate缓存数据,负载应该从缓存中给我一个副本(没有往返到DB),我要么在父项被保存回来之前这样做(因此没有提交给ParentItem的更改,仅仅是ChildItem)或之后(因此缓存版本仍然相同,我的新对象将与更新版本匹配)。我这样做时(对于ParentItemID = 1):
a different object with the same identifier value was already associated
with the session: 1, of entity: NameSpace.ParentItem
就行:
Session.SaveOrUpdate(parentItemInstance);
我猜这与我的ObjectDataSource已经加载了这个ParentItem以便更新它的事实有关,但我不知道从哪里开始。
答案 0 :(得分:1)
你的问题可能与会话有关。您是否按请求创建和关闭NHibernate会话?
问题是“我认为我能做的就是使用数据绑定控件中的ID从我的会话中加载ParentItem”。您似乎保存了从一个会话加载的对象并将其保存在另一个会话中。
您应该使用session.Merge将对象从另一个会话保存到当前会话中。你可以在这里找到一篇关于session.SaveOrUpdate和session.Merge之间区别的优秀文章:NHibernate - Difference between session.Merge and session.SaveOrUpdate?