2013-05-20 34 views
4

我在風中撲動,所以我想我會在這裏問...請讓我知道,如果這是顯而易見的,並已答覆之前。NHibernate投擲課程已關閉

我正在建立一個MVC 3網站,該網站在我用一個用戶運行它時正常工作,在這裏我點擊了頁面。但是,如果我瘋狂地刷新,最終我打了一個「會議閉幕」。

我已經隔離出了幾乎所有的存儲庫以嘗試進入底部,所以我知道它在主頁上出現錯誤。唯一在存儲庫中調用的是從數據庫表中獲取用戶名。

我使用Postgres作爲數據庫,以及NauckIT的ASP.NET成員資格提供程序。主數據庫也是Postgres(但另一個數據庫)。

會話管理使用下面的代碼完成:

public class MvcApplication : System.Web.HttpApplication 
{ 
    public static ISessionFactory SessionFactory = 
      NHibernateHelper.GetSessionFactory(); 

    public MvcApplication() 
    { 
     this.BeginRequest += MvcApplication_BeginRequest; 
     this.EndRequest += MvcApplication_EndRequest; 
    } 

    void MvcApplication_BeginRequest(object sender, EventArgs e) 
    { 
     CurrentSessionContext.Bind(SessionFactory.OpenSession()); 
    } 
    void MvcApplication_EndRequest(object sender, EventArgs e) 
    {    
     CurrentSessionContext.Unbind(SessionFactory).Dispose(); 
    } 
} 

是獲得代碼的登錄信息是:

public Login GetCurrentLogin() 
    { 
     return Session.Query<Login>().FirstOrDefault(l => l.UserID == UserAccessRepository.UserID); 
    } 

UserAccessRepository只是獲取從窗體身份驗證cookie的userid

 ninjectKernel.Bind<IUserRepository>().To<NHUserRepository>(); 
     ninjectKernel.Bind<ILeagueRepository>().To<NHLeagueRepository>().InThreadScope(); 
     ninjectKernel.Bind<ISession>() 
      .ToMethod(m => MvcApplication.SessionFactory.GetCurrentSession()) 

了一個SessionFactory來自:

會話使用注入倉庫

public class NHibernateHelper 
{ 
    private static ISessionFactory _sessionFactory; 

    public static ISessionFactory SessionFactory 
    { 
     get 
     { 
      if (_sessionFactory == null) 
      {  var rawConfig = new Configuration(); 
       rawConfig.SetNamingStrategy(new PostgresNamingStrategy()); 
       var configuration = Fluently.Configure(rawConfig) 
        .Database(PostgreSQLConfiguration.Standard.ConnectionString(ConnectionString).ShowSql().Dialect("NHibernate.Dialect.PostgreSQL82Dialect")) 
        .Mappings(m => 
           m.AutoMappings.Add(AutoMap.AssemblyOf<Event>(new AutoMapConfiguration()) 
       )).ExposeConfiguration(cfg => 
        cfg.SetProperty("current_session_context_class", "web") 
       _sessionFactory = configuration.BuildSessionFactory(); 
       Debug.WriteLine("Built SessionFactory"); 
      } 
      return _sessionFactory; 

需要明確的是,它在標準情況下,我在頁面中單擊工作正常,但當我瘋狂地擊中F5時,我得到了會議結束的問題。

更新: 不知道它是否相關,但我看到這個在BaseController,從OnActionExecuting方法的主要地方。這似乎已經清除了上述方法。

+0

我的第一個問題是:爲什麼整個'開始/ EndRequest'設置,而不是注入每個會話的生命期範圍'ISession'到控制器? –

+0

第一個例子我發現會議每個請求...高興替代..有鏈接? – Martin

+0

@ Trustme-I'maDoctor這是一種非常常見的做法......不要說這是最好的方式,但我絕對能看到它遍佈整個地方。 – BlakeH

回答

1

您不應該在網絡應用程序中使用InThreadScope()。使用InRequestScope()。編輯閱讀Object Scopes - 它最近更新了,不知道它倒退是否會浪費你的時間遲早!

如果您希望跨會員供應商使用並請求處理,您需要搜索Ninject Custom Provider(可能類似於here)。

+0

成員資格提供程序是單獨的,並且使用直接的ADO.NET而非NHibernate,因此Session不用於此部分。我會嘗試替換,並報告回 – Martin

+0

@馬丁好 - 這是你的困惑之一。底線是你需要a)綁定需要的東西'Dispose'al在除[unspecified(隱式地爲Transient)或] Transient之外的作用域,但是b)做'InThreadScope()'的東西都會阻止處置請求並導致在將來的某個時間點進行隨機處置(以及在相同線程 –

+0

:D上運行的多個請求之間的這種對象的使用,這些請求恰好已經被調度[對於它們的一些處理],必須改變一切到InRequestScope。我可能能夠通過一些優化來減少這些時間(即計算出那些實際上需要InRequestScope的那些和那些沒有的),但是現在它起作用了。 – Martin