您好,欢迎来到爱站旅游。
搜索
您的当前位置:首页利用Asp.net管道优化EntityFramework生命周期管理

利用Asp.net管道优化EntityFramework生命周期管理

来源:爱站旅游
         HttpApplication是整个ASP.NET的核心,在第一次请求到抵达后,ASP.NET会创建大量HttpApplication对象置于对象池中并保持其存活。在后续请求的时候,ASP.NET会查看对象池中有无空闲HttpApplication对象,若有则直接使用,若都处于繁忙状态则重新创建。这也就是为什么网站第一次访问的速度很慢。

        HttpApplication会不断处理ASP.NET分发给他的HTTP请求,在不同的时刻会触发不同的事件,我们可以将特定的处理程序注册到指定事件上,从而使的ASP.NET在特定时刻执行我们的业务逻辑。这就是管道的基本原理。

         在以往的代码中,为了避免互相干扰,我使用的是傻瓜式的EF生命周期管理,其代码类似这样:

        /// <summary>
        /// 获得一个实体的投影
        /// </summary>
        /// <param name="exp">筛选委托</param>
        /// <param name="selector">投影委托</param>
        /// <returns>dynamic</returns>
        public static dynamic GetPartEntity(Func<T, bool> exp, Func<T, dynamic> selector)
        {
            using (var db = new CapitalConstructionEntities())
            {
                return db.Set<T>().Where(exp).Select(selector).SingleOrDefault();
            }
        }
       而在客户端代码中,当某一个方法体内需要执行多次查询时,需要多次创建EF数据库上下文对象。DBContext这种复杂的大对象创建是非常耗时的,因为背后包含与数据库相关的非托管代码。虽然这种处理方式在小吞吐量系统中性能下降并不明显,但的确不是一种好的方式。比如下面这段代码,在一个方法内多次创建了EF上下文,造成了性能浪费:
     //保存修改
        public string SaveChanges(int id,string type)
        {
            Project modify = ProjectDao.GetEntity(p => p.Project_ID== id);
            modify.Project_Type = Trans.FCBS(type);
            if (ProjectDao.Update(modify))
            {
                return JsonConvert.SerializeObject(new { Success = true, Message = "修改成功!" });
            }
            else
            {
                return JsonConvert.SerializeObject(new { Success = false, Message = "修改失败!" });
            }
        }
        最近看了和尚兄的代码,原来数据库上下文也可以在管道事件中实例化与销毁,在单次请求中共享一个实例,性能可以提高不少。分别在开始请求和结束请求事件中创建和析构了数据库上下文对象:

class DBModule : IHttpModule
    {
        public void Dispose() { }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(
                    (object sender, EventArgs e) =>
                    {
                        context.Context.Items.Add("db", new DBContainer());
                    });

            context.EndRequest += new EventHandler(
                (object sender, EventArgs e) =>
                {
                    var db = context.Context.Items["db"];
                    if (db != null)
                    {
                        (db as DBContainer).Dispose();
                    }
                });
        }
    }
        这样一来,在一次请求中只需要实例化一次EF数据库上下文对象即可。
        此外还有使用Autofac来管理EF生命周期的,哪位同学知道,请赐教。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- azee.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务