I know that this Question is asked so many times. I have read and implemented all solution but didn't get success. I am getting this error when I retrieve data from database using EF and binds with model after that use this model on View.
My controller code 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 is
@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>
My model code is
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; }
}
}
My entity code 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 this entity has a navigation property but I don't want to that entity data so I don't want to include that.
Thanks
You don't need to check if it's disposed or not because if your DbContext is injected by the DI system then you'll never need to dispose it yourself because it will only be disposed at the end of the controller's lifespan (i.e. after the Action completes but before the View renders.
Although the DbContext implements IDisposable , you shouldn't manually dispose it, nor should you wrap it in a using statement. DbContext manages its own lifetime; when your data access request is completed, DbContext will automatically close the database connection for you.
The problem you're experiencing is due to LINQ's deferred execution. It's quite the gotcha for developers who haven't yet realized how LINQ works under the hood. I have a great blog post about it, but the core concept is that you must force an enumeration on the collection to cause the LINQ code to run immediately instead of later. This means changing this:
model.PublisherList = context.Publishers.Select(x =>
new SelectListItem()
{
Text = x.Name,
Value = x.Id.ToString()
});
to this:
model.PublisherList = context.Publishers.Select(x =>
new SelectListItem()
{
Text = x.Name,
Value = x.Id.ToString()
}).ToList();
Note the .ToList()
there which forces the enumeration.
Your LINQ query is deferred meaning that it is not being run at your controller but instead afterwards, probably in your view where you loop over the collection (which forces the enumeration and thus runs the LINQ). Because you're using the using
statement to dispose of your DB context (which is of course good practice), the context is disposed of before you reach the view, which executes the code against the disposed context. Forcing the enumeration within the using
statement will run the code at that time, instead of later when the context is disposed, and prevent this issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With