5

My base controller class, BaseController, is inherited by public-facing controllers to access a shared data context between requests with LINQ-to-SQL.

  • Am I accessing my data context in an efficient and safe way by storing it in HttpContext.Current.Items for each HTTP request?

DataContextHelper class

internal static class DataContextHelper
{
    public static MyDataContext CurrentContext
    {
        get
        {
            if (HttpContext.Current.Items["MyDataContext"] == null)
            {
                MyDataContext context = new MyDataContext();
                HttpContext.Current.Items["MyDataContext"] = context;
            }
            return (MyDataContext)HttpContext.Current.Items["MyDataContext"];
        }
    }
}

BaseController class:

public class BaseController : Controller
{
    protected MyDataContext db
    {
        get {
            return DataContextHelper.CurrentContext;
        }
    }
}

HomeController class:

[HandleError]
public class HomeController : BaseController // inherits db member
{
    public ActionResult SomeAction(string id)
    {
        User user = db.Users.First(u => u.UserId == id);
        // ... do stuff
        db.SubmitChanges();
    }
}
Petrus Theron
  • 27,855
  • 36
  • 153
  • 287

1 Answers1

4

Yes, this is a common pattern with all the major ORMs with both WebForms and MVC.

The only thing I would add a explicit dispose after each controller action is executed. just to make sure everything is disposed of correctly.

In BaseController.cs:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (HttpContext.Current.Items["MyDataContext"] == null)
            return;

        var context = (MyDataContext)HttpContext.Current.Items["MyDataContext"];

        context.Dispose();
    }
John Farrell
  • 24,673
  • 10
  • 77
  • 110
  • But if you dispose it, then there is no value in caching it (as he demonstrated in the OP) since you would need to re-instantiate it upon the next request. *Not* suggesting that caching it is a good idea, of course. – GalacticCowboy Apr 21 '10 at 16:58
  • @GalacticCowboy: jfar is right. It's only being cached until the request, which is the next action anyway. The Dispose will just force a clean-up. – Petrus Theron Apr 21 '10 at 17:01
  • Ok, I'll accept that. And you definitely do want to dispose it when you are done with it. My question is, how does this approach (instantiate in base, use in controller, dispose in base) provide any benefit? – GalacticCowboy Apr 21 '10 at 20:32
  • 1
    Less db code, more logic in actions. Convenient, since most are db-intensive. Context is only instantiated once called and can be shared by pre- and post-action calls between actions. – Petrus Theron Apr 26 '10 at 04:21