web-dev-qa-db-ja.com

ObjectContextインスタンスは破棄され、接続を必要とする操作には使用できなくなりました

私はこの見解を持っています:

@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>

私は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());
    }
}

結果のビューは次のとおりです。

@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>

このエラーが発生し続けます:

ObjectContextインスタンスは破棄され、接続を必要とする操作には使用できなくなりました。

理由がわかりません。

40
anthonypliu

問題は、LINQクエリの実行がビューでアクセスを開始するまで延期されていることだと推測しています。この時点で、dbはすでに破棄されています。

これを試して:

return View(Users.ToList());

ToList()を追加

dbを破棄する前に、DBからのフェッチを強制します。

51
Philip Fourie

using句は、Viewの前にMatchGamingEntities dbコンテキストを破棄(読み取り:破棄)していますそれを使用する機会。そのため、sersViewに渡す前に(またはそのまま)アイテムを列挙することができますが、より良いアプローチは使用を落とすusing句を使用し、実際にガベージコレクションを実行した後、その処理を実行する表示が完了するまではそうなりません。

詳細については、「 Entity Frameworkと接続プーリングに関するこの質問 」を参照してください。

11
witttness

問題はこの行です:

return View(Users.AsEnumerable());

列挙は遅延評価され、ビューが列挙を循環できるようになる前にMatchGamingEntitiesが破棄されるため、それを実行しようとするとコードは終了します。

dbオブジェクトの寿命を管理する方法を見つける必要があります。データをビューに渡す前に、メモリ内のModelオブジェクトに格納します。

同様の説明については、 here を参照してください。

10
Mike Marshall

悪い習慣ですが、設定できます

this.ContextOptions.LazyLoadingEnabled = false;

constructorContext

9
vothaison

問題は、次の場合にシャローコピーを発行していることです。

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

行う必要があるのは、UsersCopyを作成し、値をUsersCopyにコピーしてUsersを反復処理し、Deep Copyを実行するためにUsersCopyを返すことです。

何かのようなもの

List<User> UsersCopy = new List<User>();
foreach(user in Users){
  User u = new User();
  u.UserName = user.UserName;
  u.Address = user.Address;
  //...
  UsersCopy.Add(u);
}
return View(UsersCopy);
1
Travis J

子プロパティ、つまり広告申込情報の表示に問題がある場合。ここに私のために働いた汚い修正があります。オブジェクトの子アイテムを取得しないという私の問題を修正しました:

header.MachineDataLines = header.MachineDataLines;

1
Andy Singh