1

The following code works as long as I don't use the commented out using statement. When I use using I get The operation cannot be completed because the DbContext has been disposed

public IQueryable<DTOs.FormQuestionDTO> GetForm(int id, int page = 0)
{
    // FS stores pages starting with 1
    page = page == 0 ? 1 : page;

    //using (var db = new Models.FormEntities())
    //{
        var db = new Models.FormEntities();

        var questions = from fq in db.FormQuestions
                        join q in db.Questions on fq.QuestionId equals q.QuestionId
                        where (fq.FormId == id) && (fq.PageNumber == page) && fq.Disabled == false
                        orderby fq.DisplayOrder
                        select new { q.QuestionId, q.QuestionText, fq.DisplayOrder, fq.PageNumber };

        var dto = questions.Project().To<DTOs.FormQuestionDTO>();

        if (questions == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        else 
        {
            return dto;
        }
    //}
}

My original hunch was that Using is disposing of the DbContext right after the LINQ query but I got the same error when putting the .Dipose() inside of a finally block.

What's going on here? I haven't worked in C# for a while so I'm probably missing something simple.

0

2 Answers 2

5

The Entity Framework LINQ provider uses deferred execution. This means that the query is not executed on the database until the IQueryable is iterated.

What's happening is that after your context is disposed, something iterates your queryable which causes it to try to execute the database query.

You can force it to execute immediately by calling ToList().

var dto = questions.Project().To<DTOs.FormQuestionDTO>().ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that did it. Is there an equivalent method that causes execution but returns a collection of type IQueryable? Or do I have to convert the returned list back to IQueryable?
Not that I no of. I tend to think of IQueryable as an unexecuted query, so I think its fitting. Other methods that will execute an IQueryable's query are ToArray, ToDictionary, etc.
0

+1 ti @jrummell. The reason you get that error is that, when the variable declared in using leaves that scope, .Dispose() is called on it which releases the DbContext.

If you later try to execute, the DbContext is no longer there.

2 Comments

Are you certain that applies here? The original code was still within the context of Using {}; it seems more like the DbContext was yet to be created due to deferred execution.
@Jelling: He returns the IQueryable, so something presumably iterates it outside the context of the using statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.