ObjectContext实例已被释放,不能再用于需要连接的操作

ant*_*liu 40 .net c# entity-framework exception-handling asp.net-mvc-3

我有这个观点:

@model MatchGaming.Models.ProfileQuery
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>    
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm("Results", "Profiles")) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>ProfileQuery</legend>
        @Html.EditorFor(model=>model.SearchString)
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Run Code Online (Sandbox Code Playgroud)

我有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());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是结果视图:

@model IEnumerable<MatchGaming.Models.UserViewModel>    
@{
    ViewBag.Title = "Results";
}

<h2>Results</h2>

<fieldset>
    <legend>UserViewModel</legend>
    @foreach (var item in Model){
    <div class="display-label">UserName</div>
    <div class="display-field">@item.UserName</div>

    <div class="display-label">LastActivityDate</div>
    <div class="display-field">@String.Format("{0:g}", item.LastActivityDate)</div>

    <div class="display-label">Address</div>
    <div class="display-field">@item.Address</div>

    <div class="display-label">City</div>
    <div class="display-field">@item.City</div>

    <div class="display-label">State</div>
    <div class="display-field">@item.State</div>

    <div class="display-label">Zip</div>
    <div class="display-field">@item.Zip</div>
    }
</fieldset>
Run Code Online (Sandbox Code Playgroud)

我一直收到这个错误:

ObjectContext实例已被释放,不能再用于需要连接的操作.

我无法弄清楚为什么.

Phi*_*rie 51

我猜测问题是你的LINQ查询的执行被推迟到开始在你的视图上访问它们.此时db已经处理完毕.

试试这个:

return View(Users.ToList());
Run Code Online (Sandbox Code Playgroud)

添加了ToList()

这会在处置之前强制从DB中获取db.


wit*_*ess 11

您的using子句在View有机会使用之前处理(读取:销毁)MatchGamingEntities数据库上下文.因此,尽管你可以只列举的项目前(或)您通过用户搜索,更好的办法是放弃你使用的的使用条款,并让天然垃圾收集完成其工作,你真正用它做之后-这直到视图完成后才会出现.

有关更多信息,请参阅有关实体框架和连接池的此问题.


Mik*_*all 10

问题是这一行:

return View(Users.AsEnumerable());
Run Code Online (Sandbox Code Playgroud)

对枚举进行了延迟评估,并且由于您的MatchGamingEntities在视图循环遍历枚举之前被处理掉,因此代码在尝试执行此操作时会死亡.

您将不得不找到一种方法来管理db对象的生命周期,使其超出控制器方法,或者在将所有数据传递到内存模型对象之前将它们传递给视图.

在这里看到类似的解释.


vot*_*son 9

一个不好的做法,但你可以设置

this.ContextOptions.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)

在... constructorContext

  • 强调"坏".如果达到您认为需要执行此操作的程度,则需要重新考虑SOC策略. (3认同)