本文介绍了操作无法完成,因为 DbContext 已使用 MVC 4 处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我知道这个问题被问了很多次.我已经阅读并实施了所有解决方案,但没有成功.当我使用 EF 从数据库中检索数据并绑定模型时出现此错误,然后在视图上使用此模型.
我的控制器代码是
使用 System.Linq;使用 System.Web.Mvc;使用 JsonRenderingMvcApplication.Models;命名空间 JsonRenderingMvcApplication.Controllers{公共类 PublisherController :控制器{公共 ActionResult 索引(){PublisherModel 模型 = new PublisherModel();使用 (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities()){model.PublisherList = context.Publishers.Select(x =>新的选择列表项(){文字 = x.Name,值 = x.Id.ToString()});;}返回视图(模型);}}}
我的查看代码是
@model JsonRenderingMvcApplication.Models.PublisherModel@{ViewBag.Title = "索引";}<div>@Html.DisplayFor(model=>model.Id)@Html.DropDownListFor(model => model.Id, Model.PublisherList);
<div id="booksDiv">
我的模型代码是
using System.Collections.Generic;使用 System.Web.Mvc;使用 System.ComponentModel.DataAnnotations;命名空间 JsonRenderingMvcApplication.Models{公共类 PublisherModel{公共发布者模型(){PublisherList = new List();}[显示(名称=出版商")]公共 int Id { 获取;放;}公共 IEnumerable发布者列表 { 获取;放;}}}
我的实体代码是
命名空间 JsonRenderingMvcApplication.DAL{使用系统;使用 System.Collections.Generic;公共部分类发布者{公共发布者(){this.BOOKs = new HashSet();}公共 int Id { 获取;放;}公共字符串名称 { 获取;放;}公共字符串年{得到;放;}公共虚拟 ICollection书籍{得到;放;}}}
是的,这个实体有一个导航属性,但我不想要那个实体数据,所以我不想包含它.
谢谢
解决方案
您遇到的问题是由于 LINQ 的延迟执行造成的.对于尚未意识到 LINQ 是如何在幕后工作的开发人员来说,这是一个难题.我有一篇关于它的很棒的博客文章,但核心概念是您必须强制对集合进行枚举,以使 LINQ 代码立即运行而不是稍后运行.这意味着改变这个:
model.PublisherList = context.Publishers.Select(x =>新的选择列表项(){文字 = x.Name,值 = x.Id.ToString()});
为此:
model.PublisherList = context.Publishers.Select(x =>新的选择列表项(){文字 = x.Name,值 = x.Id.ToString()}).ToList();
注意强制枚举的 .ToList()
.
您的 LINQ 查询 延迟 意味着它不是在您的控制器上运行,而是在您之后运行,可能是在您循环遍历集合的视图中(这会强制枚举并因此运行 LINQ).因为您正在使用 using
语句来处理您的数据库上下文(这当然是一种很好的做法),所以在您到达视图之前处理上下文,该视图针对已处理的上下文执行代码.强制在 using
语句中进行枚举将在那个时间运行代码,而不是在处理上下文时运行代码,并防止出现此问题.
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
解决方案
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.
这篇关于操作无法完成,因为 DbContext 已使用 MVC 4 处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!