Returns Json of object in C# with Entity Framework

Asked

Viewed 1,328 times

6

I’m having a problem returning a Json using Entity Framework. The code I’m using is:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult Item(int agendaHorarioID)
{
    using (var db = new ERPContext())
    {
        IList<AgendaHorario> agendaHorario = db.AgendaHorario.Where(w => w.AgendaHorarioID == agendaHorarioID).ToList();
        var teste = agendaHorario.ToArray();
        return Json(new { HttpStatusCode.OK, dados = teste }, JsonRequestBehavior.AllowGet);
    }

}

The mistake that happens is:

A instância de ObjectContext foi descartada e não pode mais ser usada para operações que exijam uma conexão.

The reason for the problem I know, the object was not transformed into an array to take the dependency from the Entity Framework. I’ve tried many ways but I couldn’t.

  • Buddy, I don’t work with EF, I work with Nhibernate, and things are similar, I believe a way to fix this problem and work with DTO’s in the View, and serialize objects without ORM control objects, another way is to overwrite your JSON serializer, to ignore ORM control objects, in NH I do something thus, in EF there must be something to simulate. It’s just a hint.

  • @Marlon.Tiedt where exactly the error to (which line), because what you did should work without such error ?

3 answers

4


Apparently this problem occurs because of references using Lazy loading. Since the Dispose() is called because of the block using, the ERPContext no longer exists. Therefore, when an instance of AgendaHorario is serialized, there are references to some complex attribute, Lazy loading is triggered and looks for the context that no longer exists.

Instead of sending every object AgendaHorario (which could contain cyclic references), try selecting the fields you want to return via JSON and use Include to include complex properties:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult Item(int agendaHorarioID)
{
    using (var db = new ERPContext())
    {
        var dados = db.AgendaHorario.Include(m => m.PropLazy).Where(m => m.AgendaHorarioID == agendaHorarioID).Select(m => new { m.Prop1, m.Prop2 }).ToList();            
        return Json(new { HttpStatusCode.OK, dados }, JsonRequestBehavior.AllowGet);
    }

}

2

If the question is just to take the dependency from the Entity Framework, simply enumerate the result.

IList<AgendaHorario> agendaHorario = db.AgendaHorario.Where(w => w.AgendaHorarioID == agendaHorarioID).ToList();

EDIT

I don’t know your class AgendaHorario, but the attribute [JsonIgnore] avoid loading the properties that are marked with it. When I need to generate a JSON, use this attribute to avoid generating too much and unnecessary information.

  • 1

    No, using Asenumerable does not execute the query. To execute the query you can call . Tolist() as OP does or use Getenumerator().

  • 1

    @Crood therefore . Toarray() that the OP does serves no purpose given that there is transformation for . Tolist(), so is not the cause of the problem.

  • 1

    @Crood was only agreeing with the remark :) (and had not read the edit of the comment concerning Context)

  • I detailed the problem in my previous answer...

  • I missed the method. It’s the ToList() that defers the result. I will update.

0

You can take two steps to resolve this, one of them is to detach(detach) the context object, but this case is recommended when it is an object.

db.Entry(entity).State = EntityState.Detached;

In the case of a list, I would recommend removing the Tracing

db.AgendaHorario.AsNoTracking().Where(w => w.AgendaHorarioID == agendaHorarioID).ToList();

Browser other questions tagged

You are not signed in. Login or sign up in order to post.