سؤال

I have an ASP.NET MVC WebAPI project, and I have an entry point to get one survey by ID.

public IEnumerable<Models.SurveyQuestionViewModel> GetSurveyById(int id)
{
    using (ITSurveyEntities model = new ITSurveyEntities())
    {
        var questions = model.SurveyQuestions.Where(s => s.SurveyId == id).AsEnumerable();
        if (!questions.Any())
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }

        return (from q in questions
                select new Models.SurveyQuestionViewModel
                {
                    Id = q.Id,
                    Question = q.Question,
                    LongDescription = q.LongDescription,
                });
    }
}

However, when I make a request to it:

$.getJSON(apiUrl + '/' + id)
    .done(function (item) {
        surveyBusy.hide();
        var o = $('#survey-content');
    })
    .fail(function (jqXHR, textStatus, err) {
        var o = $('.error-bar');

        if (err === 'Not Found') {
            o.text('The survey you requested doesn\'t yet have any questions configured.');
        }
        else {
            o.text('An error occurred: ' + err);
        }

        o.fadeIn();
    });

I fall into the :fail handler. After inspecting the actual response via the developer tools I found that the root cause is the following:

The operation cannot be completed because the DbContext has been disposed.

Am I using this object the wrong way? I thought everything was okay because I'm calling AsEnumerable() for the initial query, thus making the round-trip to the database right up front. By the time I get to the results at the bottom it's not making any database calls. I'm just marshaling those values to the view model.

هل كانت مفيدة؟

المحلول

You are delaying the query. Try this:

return (from q in questions
                select new Models.SurveyQuestionViewModel
                {
                    Id = q.Id,
                    Question = q.Question,
                    LongDescription = q.LongDescription,
                }).ToList();

نصائح أخرى

A quick fix is to call ToList():

return (from q in questions
                select new Models.SurveyQuestionViewModel
                {
                    Id = q.Id,
                    Question = q.Question,
                    LongDescription = q.LongDescription,
                });

This will short circuit lazy loading and prevent the error from occuring.

However, an IoC container can simplify this problem with the unit of work pattern which is a good fit for web. When an HTTP verb fires off, your context is brought to life and when the session is over, IoC handles disposal of the controller. No need for using or dealing with the headaches of these errors.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top