The ObjectContext instance has been disposed and can no longer be used for operations that require a connection [duplicate]
I have this view:
@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>
I have this controller for the 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.Us开发者_开发技巧ers
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());
}
}
Here is the View for Results:
@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>
I keep getting this error:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I can't figure out why.
I am guessing that the problem is that the execution of your LINQ query has been deferred until starting to access them on your view. At this point db
has already been disposed.
Try this:
return View(Users.ToList());
Added ToList()
That will force the fetch from the DB before disposing db
.
Your using clause is disposing of (read: destroying) the MatchGamingEntities db context before the View has a chance to use it. So while you can just enumerate the items before (or as) you pass the Users to the View, a better approach is to drop your use of the using clause and let natural garbage collection do its work after you truly done with it--which won't be until after the View is done.
For more information, see this question on the Entity Framework and Connection Pooling.
The problem is this line:
return View(Users.AsEnumerable());
The enumeration is lazily evaluated, and since your MatchGamingEntities is disposed of before your view can cycle through the enumeration, the code dies when it tries to do just that.
You will either have to find a way to manage the lifetime of your db object in such a way that it lives beyond the controller method, or bring all your data into in-memory Model objects before passing them to the view.
see here for a similar explanation.
A bad practice, but you can set
this.ContextOptions.LazyLoadingEnabled = false;
in the constructor
of the Context
The problem is that you are issuing a Shallow Copy when you do:
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
};
What you need to do is make a UsersCopy and then iterate through Users copying the values to the UsersCopy and then return UsersCopy in order to do a Deep Copy
Something like
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);
In case you are having problem displaying child property i.e Line items. Here is the dirty fix that worked for me. Fixed my problem of not retrieving the child items of an object:
header.MachineDataLines = header.MachineDataLines;
精彩评论