The idea is to create a class that exposes a context but handles the storage of it in a web application.
Currently this is what I have:
public class EntityContext { private static String MAIN_CONTEXT_KEY = 'MainContext'; private static TISQLEntities _context; public static void RemoveContext() { if ( HttpContext.Current != null && HttpContext.Current.Items[MAIN_CONTEXT_KEY] != null ) { ((TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY]).Dispose(); HttpContext.Current.Items[MAIN_CONTEXT_KEY] = null; } if (_context != null) { _context.Dispose(); _context = null; } } public static TISQLEntities Context { get { if (HttpContext.Current == null) { if (_context == null) { _context = new TISQLEntities(); } return _context; } if (HttpContext.Current.Items[MAIN_CONTEXT_KEY] == null) { HttpContext.Current.Items[MAIN_CONTEXT_KEY] = new TISQLEntities(); } return (TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY]; } } }
And then in the Global.asax file:
protected void Application_EndRequest(object sender, EventArgs e) { EntityContext.RemoveContext(); }
The idea is that if this is being run with a web application, the context is created on first need (and saved to the current HttpContext) and torn down whenever the request is over.
If this is a UnitTest situation it is against created on first need and removed in the TestCleanup (Not as important in this post but just wanted to clarify the _context object).
Now the idea behind this is in the least to not have to do this:
using(TISQLEntities context = new TISQLEntities()) { .... }
Everytime I want to query. I realize this may be me being lazy, but I just think that it’s easier and cleaner to have:
EntityContext.Context.User.Select(...)
And avoids ‘using’ which I try to avoid for most cases. On top of that, I’m not creating 9001 contexts per postback.
Now what I am curious about is that am I over thinking this? Should I just keep creating a context for every method that needs one? Say on a post back I have to:
- Get the user from an ID
- Get a site from an id
- Add the Site to the User (user.Site = foundSite)
- Save the user
That could entail at least 3 contexts. Is entity framework smart enough that it’s ok to just keep creating contexts whenever?
You are implementing the equivalent of NHibernate’s session per request pattern which is a good construct in NHibernate. While I can’t say 100% for sure that it’s applicable to EF it most likely is. Further expanding on other session management patterns is the Session per Business Conversation which allows NHibernate to extend holding a session over the duration of a HttpSession by disconnecting and reconnecting the session as opposed to destroying and creating. If the EF allows a similar ability as opposed to keeping a static open connection you could look at how I implemented that pattern using AOP on my blog through my profile.