MVC 3 - An instance of ObjectContext has been deleted and can no longer be used for operations that require a connection

I am very new to C # and MVC in general, and I created my own blog blog as a test project. Although most things work up to this point, I am having trouble choosing multiple columns from LINQ queries. Only after I stumbled over the SO question did I realize that I could use the created object classes as strongly typed models to handle this. I need this because I created the database layer (which I also did not use before), and trying to pass anonymous types through this layer did not work. I understand why this was so, so I am satisfied that I am heading in the right direction.

However, this approach seems to have given me another problem. I tried a simple test to extract 2 columns from a category table: CategoryID and Name. First I tried the following:

using (MyEntities db = new MyEntities()) { var model = from c in db.Categories select new Category { CategoryID = c.CategoryID, Name = c.Name }; return View(model); } 

This caused the ObjectContext to detect an error while trying to iterate over the model in the view. After reading this question , I tried to move the return statement outside the used block and call AsEnumerable () on the model as follows:

 IEnumerable<Category> model; using (MyEntities db = new MyEntities()) { model = from c in db.Categories select new Category { CategoryID = c.CategoryID, Name = c.Name }; } return View(model.AsEnumerable()); 

However, this still gives me the same ObjectContext as the error when I try to iterate over the model in the view. So now I don’t understand why I get the error. I even tried to completely remove the using directive, but this gives me another error:

"The object or complex type" MyProjectModel.Category "cannot be constructed in a LINQ to Entities query."

If this helps, here is the appropriate code for my view:

 @model IEnumerable<MyProject.Models.Category> @foreach (var category in Model) { <p>@category.Name</p> } 

Will someone be kind enough to tell me what I am missing?

Thanks.

+4
source share
1 answer

Be careful in the controller and call .ToList() before uninstalling, to schedule the execution of the request immediately before you leave the using block (since after that it is already too late, the context has left):

 using (MyEntities db = new MyEntities()) { var model = from c in db.Categories select new Category { CategoryID = c.CategoryID, Name = c.Name }; return View(model.ToList()); // <-- .ToList() here } 

Now that this solves your specific problem, what developers or dependency injection environments usually do is create an instance of DbContext inside the BeginRequest event, store it inside HttpContext.Items so that it is available throughout the entire request and inside the EndRequest method, extract it from the HttpContext and delete it.


UPDATE:

It is also recommended that you use a view model that contains only those properties that you would like to use in this particular view:

 public class CategoryViewModel { public int Id { get; set; } public string Name { get; set; } } 

and then inside your action:

 public ActionResult Index() { using (MyEntities db = new MyEntities()) { var model = from c in db.Categories select new CategoryViewModel { Id = c.CategoryID, Name = c.Name }; return View(model.ToList()); } } 

and in view:

 @model IEnumerable<MyProject.Models.CategoryViewModel> @foreach (var category in Model) { <p> Id: @category.Id Name: @category.Name </p> } 
+11
source

All Articles