0
@foreach (Thing thing in Model) {
    @Html.Action("someAction", "someOtherController", thing)
    //kind of a PartialView but coming from another controller
}

-

public class someOtherController: Controller
{

    public PartialViewResult someAction(Thing Model)
    {
        ...
    }

When this Html.Action is getting called I get The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

This is an error I'm usually able to fix using .Include() in the appropriate place in the code.

But in this case:

  • On debugging it doesn't look like "thing" or included sub-entities have been disposed.
  • I can put a breakpoint on @Html.Action("someAction", "someOtherController", thing) but if I put a breakpoint on the first line of someAction(...) method, it is never reached.
  • I have another page using such kind of partial view and it works perfectly
  • if I generate the content in the place of @Html.Action("someAction", "someOtherController", thing) instead of calling it through the partial view, it works perfectly. -

So there must be something wrong between that call and the controller, but I can't point out what. Any idea how I could debug this further and/or solve the problem?


Somebody asked for the query:

Data access layer :

public static List<Thing> GetAllThings(string[] Include = null)
{
    using (Entities ctx = new Entities())
    {
        if ((Include != null) && (Include.Length > 0))
        {
            System.Data.Entity.DbSet<Thing> things= ctx.Things;
            System.Data.Entity.Infrastructure.DbQuery<Thing> thingQuery= things.Include(Include[0]);
            for (int i = 1, c = Include.Length; i < c; i++)
                thingQuery= thingQuery.Include(Include[i]);
            return thingQuery.ToList();
        }
        return ctx.Things.ToList();
    }
}

In controller:

public ActionResult Index()
{
    string[] include = new string[] { "Stuff1.Stuff2", "Stuff4.Stuff5.Stuff6", "Stuff7.Stuff8" };
    List<Things> things = ThingsManager.GetAllThings(include).OrderBy(x => x.Name).ToList();
    return this.View(things);
}
TTT
  • 1,848
  • 2
  • 30
  • 60
  • Where is the ObjectContext being opened and closed? – Ivo Jan 30 '14 at 16:16
  • As it works in debugging, it seems your ObjectContext is static. That's a bad practice. – Ivo Jan 30 '14 at 16:17
  • You need to provide more information for this to get answered. What is the query that populates 'items', and what does 'someAction' in 'someOtherController' do with 'item'? Generally, you are correct in that you should be able to fix this with an eager-loading 'include' statement. Verify that you are loading up all the related entities that are going to get enumerated. – Joe Brunscheon Jan 30 '14 at 16:18
  • @ivowiblo: In the main view's controller – TTT Jan 30 '14 at 16:19
  • @ivowiblo: no, it's not static – TTT Jan 30 '14 at 16:20
  • @ivowiblo - static ObjectContext IS generally a bad practice, but it's more common to wrap your DAL into a static class, which would force you to properly form your queries with eager loading based upon usage. – Joe Brunscheon Jan 30 '14 at 16:20
  • @Joe: What 'someAction' does doesn't see meaninful as it looks like this part of the code is not even been executed. I'll try to add the 'query' in the question. – TTT Jan 30 '14 at 16:22

1 Answers1

2

The exception message explains it all: your database context is falling out of scope before something is trying to enumerate a lazy-loaded related entity.

Check to make sure that you are eager-loading all your related entities that this block of code operates on:

@foreach (item dto in items) {
    @Html.Action("someAction", "someOtherController", item) //kind of PartialView but coming from another controller
Joe Brunscheon
  • 1,949
  • 20
  • 21
  • This is something I have already check. As I mentioned in the question: "If I generate the content in the place of @Html.Action("someAction", "someOtherController", item) instead of calling it through the partial view, it works perfectly." And if I put any code beyond Html.Action call in comments (empty partial view etc), I still get the error ... – TTT Jan 30 '14 at 16:33
  • Yes, but that's the whole point. When you pass it off to another controller, that's making another server-side call, at which point, the object context that produced 'items' will have been disposed already. – Joe Brunscheon Jan 30 '14 at 16:39
  • 1
    I don't know if you are leveraging partial classes on your entities or not, but if you are, you need to check that those for related entity traversal as well. I have often tripped myself up by not including a related entity that is traversed in a partial class. – Joe Brunscheon Jan 30 '14 at 16:53
  • I'm not sure if I get what I need to check but: all of the classes are Entity Frameworl-generated and both controller know them. – TTT Jan 31 '14 at 09:33
  • 1
    Ok this helped. Somewhere in the StackTrace I noticed: "[TargetInvocationException: Property accessor 'someProperty' on object '...thing...' threw the following exception:'The ObjectContext instance ...". So I included the mentionned properties one by one, even those I have no use for, until I had no exception anymore. I guess I had not had this problem doing the same thing with another class because I already needed to include all of its properties. Otherwise there would be something that I don't get. – TTT Jan 31 '14 at 10:04