无法访问已处置的对象。用XPO

时间:2015-02-16 17:37:37

标签: c# asp.net devexpress xpo


我试图坚持使用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和客户端从Utilisateur继承。

我测试了GetUserByLogin,它运行正常。当我在上面运行上面的代码时,我得到了什么:
小号

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)

请帮忙,谢谢

1 个答案:

答案 0 :(得分:1)

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

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

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

     

如果您创建了一个UnitOfWork或Session实例来执行某些操作   在当前上下文中的动作,你可以安全地处置掉   UnitOfWork或Session实例。但是如果你将持久对象传递给   另一个功能,你不应该立即处理Session或   的UnitOfWork。

     

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


您发布的代码不包含可能导致您收到的异常的错误。我想GetUserByLogin方法中存在此错误。否则,很难想象您可能会在何处处置稍后在代码中使用的Session实例。

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

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

所以,我的建议是修改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();
}