如何在另一个会话中使用延迟属性(代理对象)更新对象?

时间:2015-05-21 10:36:52

标签: c# nhibernate proxy-object

我试图在会话中获取具有延迟属性的对象,并尝试在另一个会话中更新它。但它未能这样做 错误:SecUserProxy没有持久性(实际类是SecUser)

我正在使用NHibernate 3.4。当我用Google搜索时,我发现它已经修复了bug

我也遇到过这个post,据说如果你的代理对象实现了INhibernateProxy,你可以解除对象的攻击 与NHibernate。由于NHibernate不再支持可插拔代理工厂(如Castle,LinFu等),它使用内部,我是 假设内部可能是INhibernateProxy

所以我在新会话中执行了以下操作,我想将对象更新为:

 object unprox_obj = Session
     .GetSessionImplementation()
     .PersistenceContext.Unproxy(secUserobj);

期望获得相同的对象,但使用真实类型的i-e SecUser,以便它可以更新而不会出现任何错误。但它仍然返回一个代理对象。

我无法理解发生了什么?

更新 我刚才意识到'secUserobj'不是INhibernateProxy。那么为了在另一个会话中更新我的对象,我怎样才能使它成为INhibernateProxy?

 if (secUserobj is INHibernateProxy)
 {
     unprox_obj = Session
        .GetSessionImplementation()
        .PersistenceContext.Unproxy(secUserobj);
 }

1 个答案:

答案 0 :(得分:2)

分离的对象(在一个会话中加载,并作为参考保存)可以重新附加。我们可以使用session.Merge()session.Lock()

9.4.2. Updating detached objects

  

许多应用程序需要在一个事务中检索对象,将其发送到UI层进行操作,然后将更改保存在新事务中....

     

...

     

...使用 Merge(Object o) 可以避免最后一种情况。此方法将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久性实例,则将加载该实例。该方法返回持久化实例。如果给定的实例未保存或数据库中不存在,NHibernate将保存它并将其作为新的持久化实例返回。否则,给定实例不会与会话关联。在大多数具有分离对象的应用程序中,您需要两种方法SaveOrUpdate()Merge()

19.1.4. Initializing collections and proxies

  

...
  在访问未初始化的集合之前,您还可以使用 Merge() Lock() 将以前加载的对象附加到新的ISession(或其他代理人)。不,NHibernate没有,当然不应该自动执行此操作,因为它会引入临时事务语义!   ...

因此,我们可以将分离的引用传递给.Merge(),然后使用返回的(全新的)对象引用:

MyEntity reAttached = session.Merge<MyEntity>(detached);

小心,在触摸任何分离的集合之前,应该这样做(如上所述)。