3

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

 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 类,以及如何在我的控制器中创建和使用事务?

4

2 回答 2

1

您需要将 SessionFactory 设为静态,以便所有控制器都使用相同的实例。Ayende 有一篇很好的博客文章,其中举例说明了如何做到这一点以及如何在事务中包装操作。

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 中注册动作过滤器

于 2013-01-31T19:21:58.707 回答
0

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

全球.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 的文件夹中创建了一个类:

会话工厂.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,我认为这是要走的路。

于 2013-01-31T21:33:32.627 回答