NHibernate 3.0单个SessionFactory

时间:2013-01-31 16:53:50

标签: asp.net-mvc-3 nhibernate fluent-nhibernate

现在,我的会话工厂生活在我的控制器中,并且一次又一次地被创建。如何创建一个在控制器之间共享的?

 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();
    ...
    ...

编辑我已经添加了SessionController类,如下所示:

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

    public new ISession Session { get; set; }
}

并创建了一个新的SessionFactory实用程序类

 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();
    }
 }
}

问题/疑虑:使用FluentNhibernate,我应该如何配置我的新SessionFactory类,以及如何在我的控制器中创建和使用事务?

2 个答案:

答案 0 :(得分:1)

您需要使SessionFactory静态,以便所有控制器都使用相同的实例。 Ayende有good blog post作为如何做到这一点的例子,以及如何在交易中包装动作。

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
....

然后将您的AccountController更改为...

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

最后确保在global.asax

中注册动作过滤器

答案 1 :(得分:0)

这就是我个人解决问题的方法(在DotJoe和其他网站的帮助下)

<强>的Global.asax.cs

   public static ISessionFactory SessionFactory =
             SessionProvider.BuildSessionFactory();

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

<强>控制器

  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);
    }

然后我在名为Utilities的文件夹中创建了一个类:

<强> 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();

    }
}

我希望这段代码可以帮助其他需要从EF转换为NHibernate的人。

这使我的内存管理保持在一个非常大的应用程序中,有145个用户,超过450,000kb。 (使用EF从600,000kb下降)证明了NHibernate的可扩展性。

NHProf也是强烈推荐的。它有很好的建议,并将为您的具体问题提供资源。

如果您打算使用Mono,我认为这是一种方式。