2012-07-18 70 views
1

我想要做的是在我爲NHibernate配置的保存,更新,刪除偵聽器中擁有當前用戶標識。NHibernate會話自定義數據

在我看來,最好的方法是將此信息插入ISession對象中,並在偵聽器中讀取此信息。但似乎沒有任何地方可以做到。

一種方法是實現接口,但是,我找不到任何可以繼承的示例或基類(ISession擁有太多成員)。一旦我做了我的實現,我知道監聽器可以強制轉換並獲取用戶標識。

應用程序是ASPNET MVC2與SQL Server 2008

回答

0

我想通更好,我覺得。

我剛剛創建的實施NHibernate.ISession,所以在我的方法的包裝:

public NHibernate.ISession OpenDataSession(int userId) 
{ 
    return new SessionWrapper(SessionFactory.OpenSession(), userId, this); 
} 

這樣在我的聽衆,我只是類型強制轉換爲SessionWrapper並獲得UserID屬性。

它到目前爲止效果很好,我的包裝也實現了IDisposable,所以它應該沒問題。

那麼如果有人知道更好,讓我知道。

更新:按要求提供更多見解。

SessionWrapper類定義:只實現NHibernate.ISession和重新映射方法wrappedSession(構造函數的第一個參數),如:

public DataStoreSessionWrapper(NHibernate.ISession wrappedSession, UserSession currentUser) 
    { 
    } 

    public NHibernate.EntityMode ActiveEntityMode 
    { 
     get { return WrappedSession.ActiveEntityMode; } 
    } 

    public NHibernate.ITransaction BeginTransaction(System.Data.IsolationLevel isolationLevel) 
    { 
     return WrappedSession.BeginTransaction(isolationLevel); 
    } 

的想法是,通過使用Ninject,你會綁定的NHibernate .ISession這個包裝。雖然這假設UserSession對象也可以被容器訪問,但是這是真實的,因爲UserSession可以存儲在Session包中。

UPDATE2(因爲我正在演變:D):我有另一種方式去做,我認爲它更好。

而不是有一個包裝,我有一個接口IUserSessionStore基本上有一個方法:GetUserSession(),返回UserSession對象。這個接口是所有需要這些信息的類的構造函數。

通過Ninject,我簡單地將此接口映射到名爲UserSessionStore_ASPNETSession的類,該類通過將對象存儲到ASPNET會話包中實現此目的。

很明顯,我假設這是一個網站,一切都在一個層次(沒有遠程處理,或涉及wcf)。

我相信這樣更乾淨,實施起來更快,並且它也可以使所有其他可能需要此信息的圖層受益。

謝謝!

+0

如果通過自己的方法訪問會話,您可以創建一個SessionContext類,它包含*作爲會話和數據。我在我的答案中顯示你。 – 2012-07-19 09:37:54

+0

這怎麼能工作?你應該在列表中輸入一個異常:類似於無法投射'NHibernate.Impl.SessionImpl'類型的對象來鍵入SessionWrapper – giammin 2013-08-06 09:38:56

+0

@KatLimRuiz請你提供你的SessionWrapper實現嗎? – giammin 2013-08-29 16:04:06

1

如果您使用的每個線程的會話,你可以將其存儲在一個線程靜態字段:

[ThreadStatic] 
private static int userId; 

public static void UserId { get { return userId; } set { userId = value; } } 

爲了避免從一個賬面值會話到另一個線程池,您應該重置事務結束時的值(例如,在事務提交事件中)。

注意:我正在取得巨大成功。但是我把它包裝在一些服務之後。只有一個ThreadStatic字段,它包含一個自制的TransactionContext,它包含會話和所需的所有附加數據。


當您通過自己的方法訪問會話時,可以改爲使用SessionContext類。它需要更改呼叫者,但您不必包裝會話。

事情是這樣的:

public class ISessionContext : IDisposable 
{ 
    public ISession Session { get; } 

    public SessionData Data { get; } 
} 

public ISessionContext CreateSession() 
{ 
    return new SessionContext(SessionFactory.OpenSession(), new SessionData(user)); 
} 
+0

不好,因爲ISession的是你的聽衆獲得這也正是我所需要的SessionData對象。抱歉。 – 2012-07-19 22:05:36

0

我有同樣的問題,但我的情況是不同的:

我有一個NHibernateSessionManager它處理ISessionITransaction等等等等

然後我用CallContext.SetDataNHibernateSessionManager保存編輯實體,然後我用CallContext.GetData以檢索它的IPreUpdateEventListenerIPreInsertEventListenerIPreDeleteEventListener

CallContext中的文件:

http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.aspx

在網絡方面

我用HttpContext.Current.Items