国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

《NHibernate One Session Per Request 簡(jiǎn)單實(shí)現(xiàn)》勘誤

2019-11-17 03:49:50
字體:
供稿:網(wǎng)友
使用 NHibernate 進(jìn)行 Web 開發(fā)的朋友大多都知道 session-Per-Request 模式,但網(wǎng)上真正能夠正確使用的例子不多,網(wǎng)上包括園子里好多文章犯了同一個(gè)錯(cuò)誤,而這個(gè)錯(cuò)誤確一直在散播...

先來看園子里 Flyear 的一篇文章 《NHibernate One Session Per Request 簡(jiǎn)單實(shí)現(xiàn)》。

首先對(duì) NHibernate 進(jìn)行配置沒有錯(cuò):

    <PRoperty name='current_session_context_class'>web</property>
錯(cuò)誤在類 NHinbernateSessionFactory(類名都寫錯(cuò)了) 中,NHinbernateSessionFactory.GetCurrentSession 不應(yīng)包含對(duì) HttpContext 的操作,GetCurrentSession 其實(shí)本應(yīng)很簡(jiǎn)單,請(qǐng)參見(類名改成 NHibernateHelper,簡(jiǎn)短):

    public sealed class NHibernateHelper
    {
        public static readonly ISessionFactory SessionFactory;
        static NHibernateHelper()
        {
            SessionFactory = new Configuration()
                .Configure()
                .AddAssembly(/**/)
                .BuildSessionFactory();
        }
        public static ISession GetCurrentSession()
        {
            return SessionFactory.GetCurrentSession();
        }
    }
將 current_session_context_class 配置為 web,NHibernate 在初始化時(shí)會(huì)生成 NHibernate.Context.WebSessionContext 類的實(shí)例,WebSessionContext 類源碼如下:

    [Serializable]
    public class WebSessionContext : MapBasedSessionContext
    {
        // Fields
        private const string SessionFactoryMapKey = "NHibernate.Context.WebSessionContext.SessionFactoryMapKey";

        // Methods
        public WebSessionContext(ISessionFactoryImplementor factory) : base(factory)
        {  }

        protected override IDictionary GetMap()
        {
            return (HttpContext.Current.Items[SessionFactoryMapKey] as IDictionary);
        }

        protected override void SetMap(IDictionary value)
        {
            HttpContext.Current.Items[SessionFactoryMapKey] = value;
        }
    }
WebSessionContext 實(shí)現(xiàn)了 Session-Per-Request 模式,它封裝了 HttpContext ,因此我們不需要在我們的輔助類(NHibernateSessionFactory 或是 NHibernateHelper)中再對(duì) HttpContext 進(jìn)行操作。

我們只需要從 WebSessionContext 的實(shí)例中獲取 Session 即可。從WebSessionContext 類中獲取當(dāng)前 ISession 相當(dāng)簡(jiǎn)單,因?yàn)?WebSessionContext 實(shí)現(xiàn)了 ICurrentSessionContext 接口:

    public interface ICurrentSessionContext
    {
        ISession CurrentSession();
    }


NHibernate.Context 命名空間中的類和接口

(說明:current_session_context_class 還可以配置為 Managed_web、Call、thread_static,分別對(duì)應(yīng)類 ManagedWebSessionContext、CallSessionContext、ThreadStaticSessionContext)

在實(shí)際使用中我們并不需要直接調(diào)用 WebSessionContext 的 CurrentSession() 方法,因?yàn)?ISessionFactory 提供了一個(gè)更簡(jiǎn)單的方法讓我們能一步獲取到 Session:

    public interface ISessionFactory : IDisposable
    {
        ISession GetCurrentSession();
        //......
    }


下面探討一下 ISessionFactory.GetCurrentSession 方法的具體實(shí)現(xiàn):

Configuration.BuildSessionFactory 方法實(shí)際返回的是 SessionFactoryImpl 類的實(shí)例,讓我們簡(jiǎn)單看一下 SessionFactoryImpl 的部分代碼吧:

1     public sealed class SessionFactoryImpl
2         : ISessionFactoryImplementor, IMapping, ISessionFactory, IDisposable, IObjectReference
3     {
4         private readonly ICurrentSessionContext currentSessionContext;
5
6         public ISession GetCurrentSession()
7         {
8             if (this.currentSessionContext == null)
9             {
10                 throw new HibernateException(
11                     "No CurrentSessionContext configured (set the property current_session_context_class)!");
12             }
13             return this.currentSessionContext.CurrentSession();
14         }
15
16         public ICurrentSessionContext CurrentSessionContext
17         {
18             get { return this.currentSessionContext; }
19         }
20
21         private ICurrentSessionContext BuildCurrentSessionContext()
22         {
23             string name = PropertiesHelper.GetString("current_session_context_class", this.properties, null);
24             string str2 = name;
25             if (str2 != null)
26             {
27                 if (str2 == "call") return new CallSessionContext(this);
28                 if (str2 == "thread_static") return new ThreadStaticSessionContext(this);
29                 if (str2 == "web") return new WebSessionContext(this);
30                 if (str2 == "managed_web") return new ManagedWebSessionContext(this);
31             }
32             else
33                 return null;
34             try
35             {
36                 Type type = ReflectHelper.ClassForName(name);
37                 return (ICurrentSessionContext)Environment.BytecodeProvider.ObjectsFactory
38                     .CreateInstance(type, new object[] { this });
39             }
40             catch (Exception exception)
41             {
42                 log.Error("Unable to construct current session context [" + name + "]", exception);
43                 return null;
44             }
45         }
46     //......
47     }

SessionFactoryImpl 在實(shí)例化時(shí)會(huì)調(diào)用 BuildCurrentSessionContext() 方法(行21)為 currentSessionContext 字段賦值,具體值有配置文件中的 current_session_context_class 決定。

ISessionFactory 的 GetCurrentSession()  調(diào)用的是 ICurrentSessionContext 的 CurrentSession()(行6) 方法。

上面的代碼相當(dāng)簡(jiǎn)單,想必大家都已經(jīng)明明白白了。



《NHibernate One Session Per Request 簡(jiǎn)單實(shí)現(xiàn)》 一文中還有兩處不太恰當(dāng)?shù)牡胤剑?br>
1. 并不是每一次請(qǐng)求都需要一個(gè) Session 來訪問數(shù)據(jù)庫(kù)。文中 Global.asax 的代碼給所有的請(qǐng)求在開始的時(shí)候都進(jìn)行WebSessionContext.Bind(),會(huì)照成很多 Session 的浪費(fèi),雖然 NHibernate 的 Session 是輕量級(jí)的,較為合理的做法是在“真正需要”時(shí)綁定。

2. 因?yàn)?WebSessionContext.Unbind 方法需要一個(gè) ISessionFactory 接口的實(shí)例,迫使用我們的輔助類(NHibernateSessionFactory 或是 NHibernateHelper)公開 SessionFactory。

第一個(gè)問題比較容易解決,留在回復(fù)中和大家交流吧。

第二個(gè)問題我會(huì)在下一篇隨筆中解答。



本人學(xué)習(xí) NHibernate 時(shí)間也不長(zhǎng),屬于新手,如有錯(cuò)誤,歡迎指正!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 德惠市| 横峰县| 门源| 汉源县| 南陵县| 随州市| 洛扎县| 澄江县| 泊头市| 灵川县| 台湾省| 文成县| 尼玛县| 泗洪县| 渑池县| 珠海市| 浦县| 桃源县| 阿拉善盟| 台江县| 建始县| 凌源市| 宜兴市| 油尖旺区| 瑞安市| 惠水县| 内丘县| 丰都县| 灵武市| 木里| 桐庐县| 公主岭市| 江津市| 祥云县| 盐津县| 普陀区| 阳高县| 贺兰县| 宁晋县| 闽清县| 合作市|