ISession per Request (Only when necessary)

175 views Asked by At

I'm developing an application (asp.net mvc) and I'm using ISession per request (in globa.asax I use Bind and Unbind in Begin_Request event and End_Request event). Everything works fine but sometimes (some requests) I don't need to use an ISession (a connection with database).

I'd like to know if is there any way to open an ISession only when I need and make the ISession entry in all process request (to be shared with all repositories and a unique context of transaction) ?

I'm developnig and penny auction website and my server will have many request per second and sometimes I don't need the connection, I'll use a Cache.

Thanks

Cheers

2

There are 2 answers

3
DanP On BEST ANSWER

It should be noted that opening a session does not imply opening a connection to the database. As noted in this article, the cost of opening a session is extremely low. So, in general, I wouldn't worry about requests opening a session when they don't need it; essentially you're just newing up a very lightweight object.

0
Tahbaza On

You can use an ActionFilter to do this. Here's one that I use to do exactly what you describe.

public class UsingNhibernate : ActionFilterAttribute {
    private ISession nhSession;
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        nhSession = NHHelper.OpenSession();
        nhSession.BeginTransaction();
        // set an accessible reference to your nhSession for access from elsewhere
        //   ((ApplicationController)filterContext.Controller).nHSession = nhSession; is what I do
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        try {
            if (filterContext.Exception == null && nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Commit();
            else if (nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Rollback();
        } catch (Exception ex) {
            if (nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Rollback();
            nhSession.Dispose();
            throw;
        }
        nhSession.Dispose();
        base.OnActionExecuted(filterContext);
    }
}

On each appropriate controller action (or even at the controller level to apply to all actions) you simply add the UsingNhibernate action filter like so:

[UsingNhibernate]
public ActionResult SaveSystemSetting(SystemAdminVM item) {