views:

129

answers:

1

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();
    }
}
+1  A: 

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();
    }
jfar
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
@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.
FreshCode
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
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.
FreshCode