2013-01-31 64 views
3

現在,我的會話工廠住在我的控制器,並且一遍又一遍地被創建。我如何創建一個在控制器之間共享的控件?NHibernate 3.0單SessionFactory

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

Quesions /關注:使用FluentNhibernate,應該如何我配置新的SessionFactory類,以及如何在控制器中創建和使用事務?

+1

http://ayende.com/blog/4809/refactoring-toward-frictionless-odorless-code-what-about-transactions – dotjoe

+2

您需要使工廠靜態,但請查看該鏈接以查看如何在事務中包裝每個動作。 – dotjoe

+0

該帖子引用了SessionController類型,我可以在哪裏找到它? – Chazt3n

回答

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中註冊的行爲過濾

+0

謝謝先生,真的很感謝您花時間解釋這一點。這是一個非常簡單的方法,但很像腦部手術,有助於充分掌握 – Chazt3n

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

然後我創建了一個文件夾中的一類叫做公用事業:

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強烈建議。它有很好的建議,並會爲您的具體問題提供資源。

如果你打算使用單聲道,這是我的看法。

+0

任何拒絕編輯的人都會將內存泄漏引入本帖子代碼的讀者。做得好。 – Chazt3n