This is a migrated thread and some comments may be shown as answers.

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

2 Answers 467 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Silvio Silva Junior
Top achievements
Rank 2
Silvio Silva Junior asked on 03 Dec 2013, 01:40 AM
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 Answers, 1 is accepted

Sort by
0
Accepted
Doroteya
Telerik team
answered on 06 Dec 2013, 11:37 AM
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!
0
Silvio Silva Junior
Top achievements
Rank 2
answered on 07 Dec 2013, 08:31 PM
Thanks Doroteya.

It helped me!

Regards.
Tags
Development (API, general questions)
Asked by
Silvio Silva Junior
Top achievements
Rank 2
Answers by
Doroteya
Telerik team
Silvio Silva Junior
Top achievements
Rank 2
Share this question
or