1

My project is C# .NET, MVC 5, EF6. I'm getting an ObjectDisposedException on using an object in a view that has been gotten from the database. I've read probably EVERY similar question, but .Include() does NOT work; I'm thinking the problem doesn't have anything to do with lazy loading.

The controller method:

public ActionResult Browse()
{
    List<QuestionGroup> questionGroupsWithLinks = new List<QuestionGroup>();
    using (CLASSContext context = new CLASSContext())
    {
        questionGroupsWithLinks = context.QuestionGroup.Include(qg => qg.Questions.Select(q => q.Answers))
            .Where(qg => qg.QuestionGroupID == 128).ToList();
        return View("Browse", questionGroupsWithLinks);
    }
}

I've tried having the using statement not wrap around the view, I've tried declaring questionGroupWithLinks in different places, I've tried iterating through questionGroupWithLinks and assigning one of its properties in hopes that that would load it (didn't make any difference, because the problem is only in the view. It's always loaded as long as you're in the controller method), and I've tried other things as well.

The view (simplified):

@model List<CLASSOnlineAssessments.Models.Assessments.QuestionGroup>
<div class="page-copy">
    @if (Model != null)
    {
        foreach (QuestionGroup qg in Model)
        {
            //More code here; but it always fails before this point.
        }
    }
</div>

I've tried using Model.First() to access a question group instead of foreach, but that doesn't make any difference.

Let me know if I can clarify anything or post more information.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
levininja
  • 3,118
  • 5
  • 26
  • 41
  • 1
    @abatishchev - I was wondering why, every time I tried to edit, it was already done :-) – John Saunders Dec 31 '14 at 17:32
  • 3
    You don't give any information where the exception comes from. Please look at the call stack. – Stilgar Dec 31 '14 at 17:37
  • Also, post the source code for your 3 entity types, `QuestionGroup`, `Question`, and `Answer`, along with all of their properties (especially the `virtual` ones). – danludwig Dec 31 '14 at 17:56

1 Answers1

3

Have you tried this?

public ActionResult Browse()
{
    CLASSContext context = new CLASSContext();
    List<QuestionGroup> questionGroupsWithLinks = context.QuestionGroup
        .Include(qg => qg.Questions.Select(q => q.Answers))
        .Where(qg => qg.QuestionGroupID == 128).ToList();
    return View("Browse", questionGroupsWithLinks);
}

If this does not cause the error, then it does smell like an issue with lazy loading, and you should post your source for the QuestionGroup entity as well as the Question and Answer entities so that we can provide more help.

In all likelihood you have some other virtual navigation or collection property on QuestionGroup, Question, or Answer that EF is trying to load while rendering your view. However since you disposed of the context, EF cannot lazy load it, and throws the exception.

BTW, don't use the above in production. You should always have the DbContext disposed of at the end of the request somehow. In reality, you should be doing something more like this:

public ActionResult Browse()
{
    using (CLASSContext context = new CLASSContext())
    {
        List<QuestionGroupViewModel> questionGroupsWithLinks = context.QuestionGroup
            .Include(qg => qg.Questions.Select(q => q.Answers))
            .Where(qg => qg.QuestionGroupID == 128)
            .Select(x => new QuestionGroupViewModel
             {
                 Id = x.Id,
                 // ...etc.
             })
            .ToList();
        return View("Browse", questionGroupsWithLinks);
    }
}

With the above, you completely transfer all of the data from the entity attached to the context to a ViewModel Data Transfer Object. If the ObjectDisposedException error really is coming from EF, then the above would ensure that nothing further would happen with the DbContext after it gets disposed.

danludwig
  • 46,965
  • 25
  • 159
  • 237
  • Yes, Questions and Answers are both virtual properties. But that's what `.Include()` is for, right? – levininja Dec 31 '14 at 17:46
  • 1
    Are you certain that the ObjectDisposedException is coming from the EF DbContext being disposed? Also, are there any other virtual properties in QuestionGroup, or in Question, or in Answer? You are eager loading those properties, but EF might be trying to lazy load ***other*** virtual properties on any of the 3 entities (not just QuestionGroup). – danludwig Dec 31 '14 at 17:48
  • 2
    If that still errors and you say there are no other virtual navigation properties, it sounds likely it isn't the context at all. As Stilgar says, check the call stack and full exception details – Rhumborl Dec 31 '14 at 17:48
  • @danludwig That was it! There was another property I had forgotten about that was also virtual. Thank you SO MUCH. – levininja Dec 31 '14 at 18:01