由于已使用MVC 4处理了DbContext,因此无法完成操作

我知道这个问题被问过这么多次。 我已阅读并实施了所有解决方案但未获得成功。 当我使用EF从数据库检索数据并在View上使用此模型后与模型绑定时,我收到此错误。

我的控制器代码是

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); } } } 

我的查看代码是

 @model JsonRenderingMvcApplication.Models.PublisherModel @{ ViewBag.Title = "Index"; } 
@Html.DisplayFor(model=>model.Id) @Html.DropDownListFor(model => model.Id, Model.PublisherList);

我的型号代码是

 using System.Collections.Generic; using System.Web.Mvc; using System.ComponentModel.DataAnnotations; namespace JsonRenderingMvcApplication.Models { public class PublisherModel { public PublisherModel() { PublisherList = new List(); } [Display(Name="Publisher")] public int Id { get; set; } public IEnumerable PublisherList { get; set; } } } 

我的实体代码是

 namespace JsonRenderingMvcApplication.DAL { using System; using System.Collections.Generic; public partial class Publisher { public Publisher() { this.BOOKs = new HashSet(); } public int Id { get; set; } public string Name { get; set; } public string Year { get; set; } public virtual ICollection BOOKs { get; set; } } } 

是的,这个实体有一个导航属性,但我不想要那个实体数据,所以我不想包含它。

谢谢

您遇到的问题是由于LINQ的延迟执行。 对于那些还没有意识到LINQ如何工作的开发人员来说,这是非常困难的。 我有一篇很棒的博客文章,但核心概念是你必须强制对集合进行枚举,以使LINQ代码立即运行而不是以后运行。 这意味着改变这个:

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

对此:

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

注意.ToList()会强制枚举。

您的LINQ查询是延迟的 ,这意味着它不是在您的控制器上运行,而是在您的视图中运行,可能在您的视图中循环集合(这会强制枚举并因此运行LINQ)。 因为您正在使用using语句来处理您的数据库上下文(当然这是一种很好的做法),所以在您到达视图之前会先处理上下文,该视图会针对已处置的上下文执行代码。 在using语句中强制枚举将在那时运行代码,而不是在处理上下文时运行,并防止出现此问题。