When returnin IQueryable, get the error: The ObjectScope has already been disposed and it's managed persistent objects can no longer be accessed.

3 posts, 1 answers
  1. Silvio Silva Junior
    Silvio Silva Junior avatar
    100 posts
    Member since:
    Mar 2010

    Posted 02 Dec 2013 Link to this post

    Hello.

    I have a method that return a complex type (from a stored procedure), that is working fine.

    But now, I decided to change this method to return an IQueryable object, but, when I try to do this, I get the following error:


    The ObjectScope has already been disposed and it's managed persistent objects can no longer be accessed. The ObjectScope should be disposed at the end of the life cycle of your business logic instance. This can also be done in the Dispose of your ASP page or MVC controller.
    Nome do objeto: 'OpenAccessRuntime.EnlistableObjectScope'.


    My code is:
    public class CanalComunicacaoREP : Repositorio<CanalComunicacao>, IDisposable
    {
      private
    EntitiesModel dbContext;
     
      public CanalComunicacaoREP(EntitiesModel context) : base(context) { this.dbContext = context; }
     
      public IQueryable BuscarPorEntidade(int pEntidadeID)
      {
        var result = from cc in dbContext.CanalComunicacaos
                  join cct in dbContext.CanalComunicacaoTipos on cc.CanalComunicacaoTipoID equals cct.CanalComunicacaoTipoID
                  where cc.EntidadeID == pEntidadeID
                  select new
                  {
                  cc.CanalComunicacaoID,
                  cc.Descricao,
                  cc.IsPrincipal,
                  cct.CanalComunicacaoTipoID,
                  TipoDescricao = cct.Descricao
                  };
     
                  return result.AsQueryable();
      }

    //Only for knowing, below is the method using the complex type, that works with no erros:
    public List<result_BuscarCanaisPorEntidade> BuscarPorEntidade(int pEntidadeID)

      return dbContext.Stp_BuscarCanaisPorEntidade(pEntidadeID).ToList();
    }

    }

    My Parent REP class:
    public abstract class Repositorio<T> : IRepositorio<T>
    {
      private EntitiesModel dbContext;
     
      public Repositorio(EntitiesModel context)
      {
         this.dbContext = context;
      }

       //methods
    }


    I'm using the UnitOfWork pattern:
    public class UnitOfWork : IDisposable
    {
      private readonly EntitiesModel _context;
      private CanalComunicacaoREP _canalComunicacaoREP;
     
      public UnitOfWork()
      {
        _context = new EntitiesModel();
      }
     
      public CanalComunicacaoREP CanalComunicacaoREP
      {
         get
       {
           if (this._telefoneREP == null)
           this._canalComunicacaoREP = new CanalComunicacaoREP (_context);
           return _canalComunicacaoREP;
       }
      }
     
      public void Save()
      {
        _context.SaveChanges();
      }

    My calling in aspx.cs page:
    protected void grdCanalComunicacao_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
           if (Request["EntidadeID"] != null)
           {
               using (UnitOfWork oUnitOfWork = new UnitOfWork())
               {
                   grdCanalComunicacao.DataSource = oUnitOfWork.CanalComunicacaoREP.BuscarPorEntidade(1);
                }
            }
    }

    One import point is:

    The problem occurs only if I try to set the grdComunicacao.DataSource, if I use a variable instead of  grdComunicacao.DataSource I get no errors. Ex:
    Var myvar
    oUnitOfWork.CanalComunicacaoREP.BuscarPorEntidade(1);


    I have debuged the code, and, my dbContext is not null, even my result is not null.

    What I'm doing wrong?

    Regards.
  2. Answer
    Doroteya
    Admin
    Doroteya avatar
    502 posts

    Posted 06 Dec 2013 Link to this post

    Hi Silvio,

    Excuse us for the delayed response.

    Generally, the behaviour you are experiencing is the expected one. The cause for it lies in the deferred execution of the LINQ queries. The idea is that the IQueryable variable holds only a statement which is executed once it is enumerated. In other words, in the BuscarPorEntidade() method, you are simply building a query which is passed to the DataSource property of the grid for execution. The issue here is that since the UnitOfWork variable is within a using statement, its scope is limited to the scope of the grdCanalComunicacao_NeedDataSource() method. This means that the DataSource property does not have a live instance of the context that can execute the IQueriable variable and obtain the result.  

    The reason why you are able to execute the query through another variable is that this variable is defined within the scope of the using statement.

    You can resolve the situation by defining the context as a private property of the page, to instantiate it on Page_Load(), and to dispose it with the disposal of the page. Additionally, Telerik OpenAccess ORM defines a number of good practices for managing the context in web environment. I would suggest to you the details from this section in our documentation.

    I hope this helps. If you have additional question or need further assistance, do not hesitate to get back to us.


    Regards,
    Doroteya
    Telerik
    OpenAccess ORM Q3 2013 simplifies your model operations even further providing you with greater flexibility. Check out the list of new features shipped with our latest release!
  3. DevCraft banner
  4. Silvio Silva Junior
    Silvio Silva Junior avatar
    100 posts
    Member since:
    Mar 2010

    Posted 07 Dec 2013 Link to this post

    Thanks Doroteya.

    It helped me!

    Regards.
Back to Top