Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need a ToList() to avoid disposed context errors?

I'm writing some code to access a database using EntityFrameWork. The code is:

public IEnumerable<Rows> GetRows(int id)
{
    using (var context = new ApplicationDbContext())
    {
        var repository = new EntityFrameWorkRepository<int, RowEntity>(context);
        //need a ToList() here to prevent disposed dbcontext errors
        return repository.GetRowsFromDb(id).ToList();
    }
}

GetRowsFromDb() uses LINQ to query the database and filter the results using id.

I originally wrote the above method without the ToList() call, but when I tried to access objects in the IEnumerable which was returned, I would get an exception about the dbcontext already being disposed. I don't understand how the above code fixes things, although it does then work. I assume ToList() is deep copying the object and that this perhaps provides the required separation from the context/database, but surely the original object should be usable?

like image 242
CalumMcCall Avatar asked Dec 16 '14 17:12

CalumMcCall


1 Answers

The reason you need to call ToList, ToArray, or some other method that enumerates the data returned by EF is that query execution in LINQ is deferred: the data is not processed until you take it explicitly. By the time your method returns the context through which the query data has been obtained is closed (your using block takes care of that happening quickly), causing the exception that you see.

This is done so that the code is not spending time processing the data that you do not need. For example, you could write code that starts reading through the data on the client side, and stops in the middle. If query execution were not deferred, you would have spent time and memory obtaining the "tail" of the query only to throw it away. Deferred execution puts you in control: you decide what data you want to keep as you go, or bring the entire collection to memory based on what you plan to do with the data.

like image 91
Sergey Kalinichenko Avatar answered Oct 05 '22 23:10

Sergey Kalinichenko