NHibernate 3.0 single SessionFactory

Now my Factory session lives in my controllers and is created over and over again. How do I create a share between controllers?

 public class AccountsController : Controller
{
    private static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
           .Database(MySQLConfiguration.Standard.ConnectionString(
           c => c.FromConnectionStringWithKey("DashboardModels")
       ))
   .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Accounts>())
   .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Notes>())
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Sales_Forecast>())
     .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ChangeLog>())
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Tasks>())

   .BuildSessionFactory();
    }
    ISessionFactory sessionFactory = CreateSessionFactory();
    ...
    ...

      

EDIT I added the SessionController class like this:

    public class SessionController : Controller
{
    public HttpSessionStateBase HttpSession
    {
        get { return base.Session; }
    }

    public new ISession Session { get; set; }
}

      

and created a new SessionFactory service class

 public class NHibernateActionFilter : ActionFilterAttribute
{
private static readonly ISessionFactory sessionFactory = BuildSessionFactory();

private static ISessionFactory BuildSessionFactory()
{
    return new Configuration()
        .Configure()
        .BuildSessionFactory();
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var sessionController = filterContext.Controller as SessionController;

    if (sessionController == null)
        return;

    sessionController.Session = sessionFactory.OpenSession();
    sessionController.Session.BeginTransaction();
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var sessionController = filterContext.Controller as SessionController;

    if (sessionController == null)
        return;

    using (var session = sessionController.Session)
    {
        if (session == null)
            return;

        if (!session.Transaction.IsActive)
            return;

        if (filterContext.Exception != null)
            session.Transaction.Rollback();
        else
            session.Transaction.Commit();
    }
 }
}

      

Quesions / Concerns: Using FluentNhibernate, how do I set up a new SessionFactory class and how do I create and use a transaction in my controller?

+3


source to share


2 answers


You need to make the SessionFactory static so that all controllers use the same instance. Ayende has a nice blog post for an example of how to do this, as well as how to wrap activities in transactions.

public class SessionController : Controller
{
    public HttpSessionStateBase HttpSession { get { return base.Session; } }
    public new ISession Session { get; set; }
}

//you could put this class in the same physical file as the SessionController.cs 
//since they are tightly coupled to each other
public class NHibernateActionFilter : ActionFilterAttribute
....

      

then change your AccountController to ...



public class AccountsController : SessionController
{
    public ActionResult Index()
    {
         //Session is primed and ready for use
    }
}

      

Make sure to register your action filter in global.asax

+1


source


This is how I personally solved my problem (using DotJoe and others on this site)

Global.asax.cs

   public static ISessionFactory SessionFactory =
             SessionProvider.BuildSessionFactory();

    protected void Application_Start()
    {       
        SessionFactory.OpenSession();
    }

      

controller

  public ActionResult ReadAccounts([DataSourceRequest] DataSourceRequest request)
    {
        DataSourceResult result;

        using(ISession session = TRX.CRM.Dashboard.Web.UI.MvcApplication.SessionFactory.OpenSession())
        {
            using (ITransaction tx = session.BeginTransaction())
            {
                var customers = session.Query<Accounts>().Where(a => a.Deleted == false).AsNoTracking();
                //from customer in session.Query<Accounts>().AsNoTracking()
                //                where !customer.Deleted
                //                select customer;
                result = customers.ToDataSourceResult(request);
                tx.Commit();
            }
        }
        return Json(result, JsonRequestBehavior.AllowGet);
    }

      

Then I created a class in the Utilities folder:



SessionFactory.cs

public class SessionProvider  
{
   public static ISessionFactory BuildSessionFactory()
   {
     return Fluently.Configure()
          .Database(MySQLConfiguration.Standard.ConnectionString(
          c => c.FromConnectionStringWithKey("DashboardModels")
      ))
     .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Accounts>())
     .BuildSessionFactory();

    }
}

      

I hope this code can help anyone who needs to translate from EF to NHibernate as a last resort.

This allowed me to keep my memory management in a fairly large application with 145 users down to just over 450,000 KB. (compared to 600,000KB using EF) is a testament to the scalability of NHibernate.

NHProf is also recommended. It has great suggestions and will provide resources for your specific problem.

If you are going to use Mono this is the way to go in my opinion.

0


source







All Articles