ObjectContext实例已被释放,不能再用于需要连接的操作。
ObjectContext实例已被释放,不能再用于需要连接的操作。
我有这个视图:
@model MatchGaming.Models.ProfileQuery @{ ViewBag.Title = "Index"; }} @Html.ActionLink("Back to List", "Index")Index
@using (Html.BeginForm("Results", "Profiles")) { @Html.ValidationSummary(true)
我有这个HttpPost的控制器:
[HttpPost] public ActionResult Results(ProfileQuery profileQuery) { Debug.Write(profileQuery.SearchString); using(var db = new MatchGamingEntities()) { var SearchUserName = db.Users.SingleOrDefault(a=> a.UserName.Contains(profileQuery.SearchString)); var Users = from m in db.Users join m2 in db.MyProfiles on m.UserId equals m2.UserId where m.UserName == SearchUserName.UserName select new UserViewModel { UserName = m.UserName, LastActivityDate = m.LastActivityDate, Address = m2.Address, City = m2.City, State = m2.State, Zip = m2.Zip }; return View(Users.AsEnumerable()); } }
这是Results的视图:
@model IEnumerable@{ ViewBag.Title = "Results"; } Results
我一直收到这个错误:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
我弄不明白为什么。
使用using
语句将MatchGamingEntities数据库上下文销毁后,View无法使用它。所以在将Users传递给View之前(或同时),您可以枚举这些项,但更好的方法是删除使用 using语句,并在真正完成后让自然垃圾回收处理它-这将在View完成之后才会发生。
更多信息,请参见Entity Framework和连接池的这个问题。
问题的原因是using
语句在将MatchGamingEntities数据库上下文传递给View之前销毁了它。解决方法是删除using
语句,让垃圾回收在View完成后处理它。
问题原因:在访问视图时,LINQ查询的执行被延迟,因此在这个时候,db
已经被销毁了。
解决方法:使用ToList()
方法来强制从数据库中获取数据,然后再销毁db
。
然而,尝试这个方法后,出现了"Object reference not set to an instance of an object."的错误。这个错误发生在你指定的那行代码上,这就是抛出异常的原因。
在我的示例中,我删除了不必要的AsEnumerable()
,因为ToList()
已经是可枚举的了。看一下视图代码,可能是因为LastActivityDate为null导致了NullReferenceException,因为在String.Format()中使用了它。理论上,这个方法应该是可行的。否则,可以逐步调试代码,找到空引用的位置,很可能是Users对象或者视图中的某些内容。
然而,我尝试了这个方法,但没有起作用。我认为问题的一部分是我的第一个视图没有正确地传递ProfileQuery模型,因为我尝试打印profileQuery.SearchString时出现了空引用异常,所以SearchString甚至没有传递到HttpPost。
问题的出现原因是在返回视图的代码中,使用了延迟评估的枚举(Enumeration),而在视图遍历枚举之前,MatchGamingEntities已被释放,因此代码在尝试执行遍历操作时失败。
解决方法之一是找到一种方法来管理db对象的生命周期,使其在控制器方法之外继续存在,或者在将数据传递给视图之前,将所有数据都存储在内存中的模型对象中。
可以参考这里获取类似解释的更多信息。