40 votes

L'instance ObjectContext a été supprimée et ne peut plus être utilisée pour des opérations nécessitant une connexion.

J'ai cette vue:

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

J'ai ce contrôleur pour le 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());
    }
}
 

Voici la vue des résultats:

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

Je continue à avoir cette erreur:

L'instance ObjectContext a été supprimée et ne peut plus être utilisée pour des opérations nécessitant une connexion.

Je ne peux pas comprendre pourquoi.

51voto

Philip Fourie Points 12889

Je suppose que le problème est que l'exécution de votre requête LINQ a été différée jusqu'à ce que vous commenciez à y accéder de votre point de vue. À ce stade, db a déjà été éliminé.

Essaye ça:

 return View(Users.ToList());
 

Ajouté ToList ()

Cela forcera l'extraction de la base de données avant de disposer de db .

11voto

witttness Points 539

Votre utilisation de la clause est de l'élimination de (lire: destruction) de la MatchGamingEntities db contexte avant que la Vue a une chance de l'utiliser. Ainsi, alors que vous pouvez simplement énumérer les éléments avant (ou) vous passez les Utilisateurs de la Vue, une meilleure approche consiste à déposer votre utilisation de l' aide de la clause et laissez naturelle de collecte des ordures faire son travail après avoir terminé avec elle,--ce qui ne sera pas jusqu'à ce que après le point de Vue est fait.

Pour plus d'informations, consultez cette question sur Entity Framework et le Regroupement de Connexion.

10voto

mjmarsh Points 5858

Le problème vient de cette ligne:

return View(Users.AsEnumerable());

L'énumération est paresseusement évalué, et depuis votre MatchGamingEntities est éliminé à l'avant de votre point de vue peut faire un cycle par l'énumération, le code meurt lorsqu'il tente de le faire.

Vous devrez trouver un moyen de gérer la durée de vie de votre db objet de telle manière qu'il vit au-delà de la méthode de contrôleur, ou apporter toutes vos données dans la mémoire les objets de Modèle avant de passer à la vue.

voir ici pour une explication similaire.

9voto

vothaison Points 81

Une mauvaise pratique, mais vous pouvez définir

 this.ContextOptions.LazyLoadingEnabled = false;
 

dans les constructor des Context

1voto

Travis J Points 28588

Le problème est que vous émettez une copie superficielle lorsque vous procédez comme suit:

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

Ce que vous devez faire est de créer une UsersCopy, puis de parcourir les utilisateurs en copiant les valeurs dans UsersCopy, puis de renvoyer UsersCopy afin de créer une copie complète.

Quelque chose comme

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X