1


我正在尝试保留一个 XPObject。这是我的代码:

Administrateur adm = (Administrateur)GetUserByLogin("admin");
Client clt = (Client)GetUserByLogin("client");
using(var uow = new UnitOfWork())
                {
                    Calendrier cal = new Calendrier(uow)
                    {
                        //Some string and int attributes
                        Administrateur = adm,
                        Client = clt
                    };
                    uow.CommitChanges();
                }

GetUserByLogin是一个返回Utilisateur对象的方法,其中Administrateur和 Client 继承自Utilisateur.

我测试过GetUserByLogin,它工作正常。当我运行上面的代码时,我得到的是:
S

ystem.ObjectDisposedException: Cannot access a disposed object.
Object name: 'ASTDataLayer.POCO.Administrateur(1004)'.
   at DevExpress.Xpo.PersistentBase.get_Session()
   at DevExpress.Xpo.Session.ThrowIfObjectFromDifferentSession(Object obj)
   at DevExpress.Xpo.Metadata.XPMemberInfo.ProcessAssociationRefChange(Session s
ession, Object referenceMemberOwner, Object oldValue, Object newValue, Boolean s
kipNonLoadedCollections)

请帮忙,谢谢

4

1 回答 1

1
using (UnitOfWork uow = new UnitOfWork() {
  // Do something
}

using (UnitOfWork uow = new UnitOfWork() {
  // Do something
  return persistentObjectOrCollectionOfPersistentObjects;
}

关于何时以及如何处理 Session 或 UnitOfWork 存在很大的困惑。上面的代码片段说明了正确和错误的方法。

如果您创建 UnitOfWork 或 Session 实例只是为了在当前上下文中执行某些操作,您可以安全地处置 UnitOfWork 或 Session 实例。但是,如果您将持久对象传递给另一个函数,则不应立即处置 Session 或 UnitOfWork。

在后一种情况下,处理 UnitOfWork/Session 实例的任务变得棘手。您必须确保您的任何代码都不会使用 Session/UnitOfWork 在处理后加载的持久对象。


您发布的代码不包含可能导致您收到异常的错误。我想这个错误存在于 GetUserByLogin 方法中。否则,很难想象您以后可以在哪里处理代码中使用的 Session 实例。

GetUserByLogin 方法很可能是创建一个新的 Session 实例。显然,这是必要的,也是无法避免的。但是这个方法不能处理 Session,因为它返回一个持久对象作为结果。该对象将在以后使用,并且可以出于某些目的访问 Session。在使用 GetUserByLogin 方法的代码中处理 Session 是正确的。

但是,还有另一个问题。由于您的应用程序逻辑需要在同一上下文中多次调用 GetUserByLogin 方法,因此如果您尝试将返回的对象一起使用,您将混合不同的会话。例如,将它们分配给第三个对象的引用属性。顺便说一句,这就是你所做的。

因此,我的建议是修改 GetUserByLogin 方法,使其接受 Session 作为参数。在这种情况下,您将始终确保您使用的是单个 Session 实例,并且可以在退出上下文之前释放它。

using(var uow = new UnitOfWork())
{
    Administrateur adm = (Administrateur)GetUserByLogin(uow, "admin");
    Client clt = (Client)GetUserByLogin(uow, "client");
    Calendrier cal = new Calendrier(uow)
    {
        //Some string and int attributes
        Administrateur = adm,
        Client = clt
    };
    uow.CommitChanges();
}
于 2015-02-17T07:56:39.853 回答