The operation cannot be completed because the DbContext has been disposed using MVC 4

asp.net-mvc c# dbcontext entity-framework linq

Question

I am aware that this question is frequently posed. Despite reading and applying every suggestion, I was unsuccessful. When I use EF to retrieve data from a database and bind it to a model before utilizing that model on a view, I encounter this problem.

The controller code I use is

using System.Linq;
using System.Web.Mvc;
using JsonRenderingMvcApplication.Models;

namespace JsonRenderingMvcApplication.Controllers
{
    public class PublisherController : Controller
    {
        public ActionResult Index()
        {
            PublisherModel model = new PublisherModel();
            using (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities())
            {               
                model.PublisherList = context.Publishers.Select(x =>
                                        new SelectListItem()
                                        {
                                            Text = x.Name,
                                            Value = x.Id.ToString()
                                        }); ;
                           }
            return View(model);
        }

    }
}

"My View code"

@model JsonRenderingMvcApplication.Models.PublisherModel

@{
    ViewBag.Title = "Index";
}
<div>
    @Html.DisplayFor(model=>model.Id)
    @Html.DropDownListFor(model => model.Id, Model.PublisherList);
</div>
<div id="booksDiv">

</div>

I'm using model code.

using System.Collections.Generic;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;

namespace JsonRenderingMvcApplication.Models
{
    public class PublisherModel
    {
        public PublisherModel()
        {
            PublisherList = new List<SelectListItem>();
        }

        [Display(Name="Publisher")]
        public int Id { get; set; }
        public IEnumerable<SelectListItem> PublisherList { get; set; }
    }
}

The entity I am is

namespace JsonRenderingMvcApplication.DAL
{
    using System;
    using System.Collections.Generic;

    public partial class Publisher
    {
        public Publisher()
        {
            this.BOOKs = new HashSet<BOOK>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public string Year { get; set; }

        public virtual ICollection<BOOK> BOOKs { get; set; }
    }
}     

Yes, the navigation property for this object exists, but I don't want to include that in the entity data.

Thanks

1
20
1/19/2014 3:24:07 AM

Accepted Answer

The deferred execution of LINQ is the cause of the issue you're having. For developers who haven't yet grasped the inner workings of LINQ, it's quite the gotcha. The main idea is that you must compel the collection to undergo an enumeration to have the LINQ code execute now rather than later. I have a nice blog post about it. This calls for changing:

model.PublisherList = context.Publishers.Select(x =>
    new SelectListItem()
    {
        Text = x.Name,
        Value = x.Id.ToString()
    });

on this:

model.PublisherList = context.Publishers.Select(x =>
    new SelectListItem()
    {
        Text = x.Name,
        Value = x.Id.ToString()
    }).ToList();

Recall the.ToList() which compels the enumeration exists.

Your LINQ query is deferred, suggesting it gets executed later, most likely in your view when you loop around the collection (which forces the enumeration and thus runs the LINQ). since you're utilizing theusing The context is disposed of before you reach the view, which runs the code against the disposed context. This is obviously good practice. statement to dispose of your DB context. requiring the count to be done within theusing statement will execute the function then, rather than when the context is destroyed, avoiding this problem.

62
1/19/2014 4:24:26 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow