Reputation: 1605
Situation: What I'd like to do is have access to the data context for the life cycle of a page. This is primarily to (a) avoid series of using() and to avoid (b) out of scope exceptions in the view when a lazy loaded property is accessed.
Edit: I'm using MVC 4 and Entity Framework 4.3.1 (the latest)
What I typically do is
using (MyDB b = new MyDB()) {
...do all my stuff
}
In my controller or the data layer. The nice thing about this, based on my reading, is it's clean, causes no memory leaks etc. But the disadvantage is that even for the lifecycle of a single page I end up doing this again and again, and my objects lose context in the view as I've already disposed of the context.
I did some reading and found a similar post from 2009 but with no code in the answer. Surely some others have figured out how to solve this - I figure I have to do something with
Application_BeginRequest and EndRequest
But I'm just not sure how, and what the gotchas/best practices are.
Thank you for your help (with some code sample if possible!)
Upvotes: 1
Views: 2058
Reputation: 1138
you can return before you exit the using block so the context will be in scope when lazy loading in the view
using (MyDB b = new MyDB()) {
...do all my stuff
return View(b.Data);
}
Upvotes: 0
Reputation: 13381
First don't use lazy loading (Entity Framework goes to the database and brings the results back one row at a time) in the views as queries from the views are bad practice and result in Select N+1 (Select N + 1 is a data access anti-pattern where the database is accessed in a suboptimal way.) or similar bad practices.
Using more than one object context means using more than one database connection per request, resulting in additional strain on the database and slower overall performance also each object context is not aware of the entities that are tracked by the other object context and might have to query the database again for its current state or have to issue an unnecessary update
When writing views, you shouldn't be bothered with thinking about persistence, or the number of queries that you views are generating.
Summary:
Perform all your queries in the action.
Force an eager load of the collection using the Include
method to specify what pieces of the object model you want to include in the
initial query.
Regards
Upvotes: 1
Reputation: 11740
The way you wish to use your datacontext is absolutely a no-no (unless you are handling a couple of hundred lines database, in which case why EF at all).
But if you have a real production sized database, pinning the context to application scope will result in the following:
The EF context is IDisposable with a very good reason: it is expected to be used in compact, short operations, and yes: you are supposed to do the using(...) "thing" all the time.
All the above is only a concern if you are building a website, intranet soluton, etc that will be used by more then one person.
Upvotes: 1
Reputation: 1604
I see you have a tag for asp.net MVC so I assume that is what you're using.
You should be implementing a repository approach like http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Anyways, all you really need to do is something like this on each of your controllers
private MyDB b = null;
public MyController()
{
b = new MyDB();
}
protected override void Dispose(bool disposing)
{
b.Dispose();
base.Dispose(disposing);
}
Upvotes: 2