I'm creating a forum which is made up of topics, which are made up of messages.
When I try to implement the topic View in my Controller with:
public ActionResult Topic(int id) //Topic Id
{
using (var db = new DataContext())
{
var topic = db.Topics.Include("Messages").Include("Messages.CreatedBy").Include("CreatedBy").FirstOrDefault(x => x.Id == id);
//include the messages for each topic, and when they were created so that the last message can be displayed on the topic page
return topic != null ? View(topic) : View();
}
}
I get this error when I try to view the topic page:
ObjectDisposedException was unhandled by user code
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
The error doesn't seem specific to a certain line, as when I remove the offending line, the same error apperars earlier on.
I have solved this by using:
DataContext db = new DataContext();
at the start of the controller and:
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
at the end (and taking using
out)
Although this works, I am curious as to why "Using" doesn't work, and I'm not really happy having the connection open throughout the controller, and disposing of it manually at the end.
Do any of your entities have lazy loading enabled? It seems like there are queries getting executed in your views but you are disposing your context before they get executed (hence the error saying it is already disposed). If you put the disposal in the controller Dispose method, the view will get executed before the controller and context is disposed.
I recommend installing Glimpse.Mvc5 and Glimpse.EF6 packages. Once you configure glimpse you can see every query that gets executed in your page. You might be surprised to see a few additional queries get executed that you did not intend. This is why I don't recommend using entities directly in your views.
This is happening because generally LINQ entities are proxy objects. If you have something like MyEntity.ChildEntities
, the underlying SQL query isn't executed to fetch those objects until the code is executed. If you're accessing them in a view, the view isn't bound until after the action method returns, at which point the DbContext is already disposed.
The lifecycle looks something like this:
topic
runs, but any additional accessors in the view that trigger more SQL queries are not executed yet.using
just disposed your DbContext.Here's a good resource on lazy loading with entities.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With