Solving The ObjectContext instance has been disposed and can no longer be used for operations that require a connection InvalidOperationException
By default Entity Framework uses lazy-loading for navigation properties. That's why these properties should be marked as virtual - EF creates proxy class for your entity and overrides navigation properties to allow lazy-loading. E.g. if you have this entity:
public class MemberLoan
{
public string LoandProviderCode { get; set; }
public virtual Membership Membership { get; set; }
}
Entity Framework will return proxy inherited from this entity and provide DbContext instance to this proxy in order to allow lazy loading of membership later:
public class MemberLoanProxy : MemberLoan
{
private CosisEntities db;
private int membershipId;
private Membership membership;
public override Membership Membership
{
get
{
if (membership == null)
membership = db.Memberships.Find(membershipId);
return membership;
}
set { membership = value; }
}
}
So, entity has instance of DbContext which was used for loading entity. That's your problem. You have using
block around CosisEntities usage. Which disposes context before entities are returned. When some code later tries to use lazy-loaded navigation property, it fails, because context is disposed at that moment.
To fix this behavior you can use eager loading of navigation properties which you will need later:
IQueryable<MemberLoan> query = db.MemberLoans.Include(m => m.Membership);
That will pre-load all memberships and lazy-loading will not be used. For details see Loading Related Entities article on MSDN.
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. in Reference table
You are trying to access an association property Country
after the data context has been disposed. Entity Framework, by default, loads association properties lazily. In other words, it makes another trip to the database when you try to access the association property for the first time. To make this trip to the database, Entity Framework must use a data context. In your case, it would be trying to use the data context created by jQGridDemoEntities db = new jQGridDemoEntities()
which has unfortunately been disposed at this point in your code. The data context has been disposed because you've exited the using block.
You have three options to get around this problem:
Access the association property when the data context is still alive. More concretely, move your code where you access the association property into your using block
Eagerly load the association property as explained in the first link I specified
customers = db.Customers.Include(c => c.Country).ToList()
Explicitly select what you want to return from the database while the data context is still alive. And use that information to construct the json object your return.
customers = db.Customers.Select(c => new
{
c.Id,
c.FirstName,
c.LastName,
c.Address,
c.Email,
c.Phone,
CountryName = c.Country.Name,
c.Note
};
How can I fix The ObjectContext instance has been disposed
This issue often stems from the serializer which will be touching all properties on the entity being serialized to send to the view. If the DbContext the entity was associated with gets disposed, the serializer will hit this when attempting to issue queries to load the related details.
The quick fix, if noteManager.ListQueryable()
returns IQueryable<Note>
would be:
return View(noteManager.ListQueryable()
.Include(x => x.Owner)
.Include(x => x.Comments)
.Include(x => x.Category)
.Include(x => x.Likes)
.Where(x => x.IsDraft == false && x.IsApproved == true)
.OrderByDescending(x => x.ModifiedOn)
.Take(10).ToList());
This eager loads the related entities along with the notes. The difference between eager loading and lazy loading is that with an eager load, EF will generate SQL to Join all of the associated tables then retrieve the related rows for the up to 10 selected rows. With lazy loading you might have 10 note rows, ID's 1-10 for instance, but as each property is touched, EF will generate a queries like:
SELECT * FROM Owners WHERE OwnerID = 22
-- Owner ID on note 1
SELECT * FROM Comments WHERE NoteId = 1
SELECT * FROM Categories WHERE CategoryId = 4
Category ID on note 1
SELECT * FROM Likes WHERE NoteId = 1
Then repeat that 9 more times, once for each note row returned. That is a lot of queries that EF and the DB need to negotiate while the entity's proxy is holding a weak reference to the DbContext. If the request disposes of the DbContext before the serializer finishes with the entity, you're handed a steaming Exception.
However, Even with eager loading this can be a rabbit hole if any of those related entities have child entities themselves. There is also the performance/resource implications of loading all of that related data that your view probably won't need.
The better long term solution is to define serializable ViewModels to represent the data structure your view actually needs to display, then leverage Select
or Automapper's ProjectTo
to fill that view model with data from the entity structure. This negates the need to eager load data, just Select
from the structure and EF will work out the SQL. It also removes the risk of lazy load hits in the serializer provided you Select
fields from the entities and not the entities themselves. This also can greatly reduce the amount of memory needed on the server & client to store the data when requested, and the data transmission size.
Passing view models to the view means passing the same, or different view models back to the server rather than trying to pass back entities, attach, and save... Which looks like more work and a time saving compared to loading the data again and copying the values across. However, this is much safer as you don't risk stale, incomplete, or potentially tampered data overwriting your real data. You should always reload the entities when performing an update anyways to validate and check that the row(s) have not been modified since they were sent to the client. Trust nothing that comes from a web client. Copying fields to a freshly loaded entity also means more efficient UPDATE
statements as Attaching + EntityState.Modified or using DbContext.Update()
result in update statements that update all fields, vs with copy across, only the values that are changed will be added to the UPDATE statement.
error:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
Company
should be lazy-loaded in your case. But your entity now in detached state (context which loaded KBrand
entity now disposed. So, when you are trying to access Company
property, Entity Framework tries to use disposed context to make query to server. That gives you exception.
You need to attach your KBrand
entity to current context in order to enable lazy-loading
RSPDbContext c = new RSPDbContext();
KBrand co = item.Tag as KBrand;
c.KBrands.Attach(co);
// use co.Company
OR you need to use eager loading, to have Company
already loaded. Something like this when you getting items:
RSPDbContext db = new RSPDbContext();
var brands = db.KBrands.Include(b => b.Company).ToList();
// assign brands to listbox
I'm getting The ObjectContext instance has been disposed, even though nothing has been disposed
You're passing a lazily-loaded EntityFramework ICollection
to the Json(..)
method. At the time that the response is serialized, the EntityFramework context will have been disposed.
Add .ToList()
to the end of your ICollection
/IQueryable
/IEnumerable
, before you pass it.
return Json(meta.ToList(), JsonRequestBehavior.AllowGet);
ASP.NET MVC5: The ObjectContext instance has been disposed
Solution found.
In this case me helped 2 methods:
1) context.Configuration.LazyLoadingEnabled = false;
2) or using .Include()
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.'
You're getting exception because of this: get_CarGame()
.
Code inside original post doesn't match your actual code.
Somewhere inside actual MainPageController.GetUserInfo
you're trying to read ApplicationUser.CarGame
. And yes, this is lazy loading issue.
GetLoggedInUserInDB
returns instance of proxy class, derived from ApplicationUser
, and disposes original context. When GetUserInfo
tries to get CarGame
property value, proxy attempts to read it from database, using disposed context. As a result, exception is being thrown.
If you really need CarGame
inside UserInfoModel
:
- either turn off lazy loading as shown above, and use eager loading;
- use projection (that is,
Select
) to retrieve user info asUserInfoModel
in place. In this case there is no need inGetLoggedInUserInDB
method at all.
Anyway, attaching LoggedUser to another context is not a way to go.
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. - List
You should include them in your original query. You can do this using Include
:
List<Item> items;
using (var context = new YourContext())
{
items = context.Items.Include(x => x.Messages).ToList();
}
Related Topics
How to Convert a C# String Value to an Escaped String Literal
Why Is Access to the Path Denied
Why Catch and Rethrow an Exception in C#
C# 3.0 Auto-Properties - Useful or Not
Asp.Net Identity'S Default Password Hasher - How Does It Work and Is It Secure
How to Change Row Color in Datagridview
Cannot Run ASP.NET 5 from Docker
Problem With Converting Int to String in Linq to Entities
Show/Hide the Console Window of a C# Console Application
How to Get the Datetime For the Start of the Week
How to Export Datatable to Excel
Passing Arguments to C# Generic New() of Templated Type