3

現在、私のセッションFactoryは私のコントローラーにあり、何度も作成されています。コントローラ間で共有されるものを作成するにはどうすればよいですか?

 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と他の人の助けを借りて)

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も強くお勧めします。それは素晴らしい提案を持っており、あなたの特定の問題のためのリソースを提供します。

あなたがモノを使うつもりなら、これは私の意見では行く方法です。

于 2013-01-31T21:33:32.627 に答える