Подтвердить что ты не робот

Экземпляр 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 был удален и больше не может использоваться для операций, требующих подключения.

Я не могу понять, почему.

4b9b3361

Ответ 1

Я предполагаю, что проблема в том, что выполнение вашего запроса LINQ было отложено до того, как вы получили доступ к ним на вашем представлении. На этом этапе db уже был удален.

Попробуйте следующее:

return View(Users.ToList());

Добавлен ToList()

Это приведет к извлечению из базы данных перед удалением db.

Ответ 2

В с использованием предложения выполняется удаление (чтение: уничтожение) контекста сопоставления MatchGamingEntities до того, как Вид имеет возможность использовать его. Таким образом, хотя вы можете просто перечислять элементы до (или как), вы передаете пользователей в Вид, лучше использовать отказаться от использования , используя, и естественная сборка мусора выполняет свою работу после того, как вы действительно сделали с ней - это будет не до тех пор, пока не будет выполнен вид.

Для получения дополнительной информации см. этот вопрос в структуре Entity Framework и пуле соединений.

Ответ 3

Проблема заключается в этой строке:

return View(Users.AsEnumerable());

Перечисление оценивается лениво, и поскольку ваши MatchGamingEntities удаляются до того, как ваше представление может циклически перебираться по перечислению, код умирает, когда он пытается сделать именно это.

Вам нужно будет либо найти способ управления временем жизни вашего объекта db таким образом, чтобы он находился за пределами метода контроллера, либо довел все ваши данные до объектов модели памяти до передавая их в представление.

см. здесь для аналогичного объяснения.

Ответ 4

Плохая практика, но вы можете установить

this.ContextOptions.LazyLoadingEnabled = false;

в constructor Context

Ответ 5

Проблема в том, что вы делаете мелкую копию, когда вы делаете:

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

Что вам нужно сделать, это сделать UserCopy, а затем выполнить итерацию через пользователей, копирующих значения в UsersCopy, а затем вернуть UsersCopy, чтобы сделать Deep Copy

Что-то вроде

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

Ответ 6

Если у вас возникла проблема с отображением дочернего объекта i.e. Вот грязное исправление, которое сработало для меня. Исправлена ​​проблема не извлечения дочерних элементов объекта:

header.MachineDataLines = header.MachineDataLines;