zoukankan      html  css  js  c++  java
  • 再议在Asp.Net中缓存ADO.Net Entity

      上一篇文章中,曾经讲在Asp.Net中采用ADO.Net Entity做缓存的处理方式,就是继承默认的ObjectContext,在保存更新时,Detach所有被Attach过的实体。曾经认为是天衣无缝,其实根本没考虑到在附加实体后,保存更新前,这中间如果出现异常的情况。比如有一个页面有这样的语句:

    var DB = new DBContext(); //实体上下文
    var person = EmployeeHelper.GetPersonByID(id);   //从缓存中取数据
    DB.Attach(person);
    person.Name = "流川枫";
    person.JoinDate = DateTime.Parse(Request["date"]);
    ……
    DB.SaveChanges();
    

      如果Request["date"]不是一个有效的日期格式,页面在执行到DB.SaveChanges()之前就会抛出异常,不但本次修改失败,而且以后所有试图修改此条记录的请求也将失败,直到此条记录的缓存过期。

      因此,我们仍然需要保证在即使保存失败,缓存的实体也能从实体上下文脱离,继续保持可更新的机制。就脱离上下文的方式,我试过好几种方式,最终唯一靠谱的就是:将这个上下文彻底销毁,皮之不存,毛将焉附。所以,虽然不情愿,却必须建立对实体上下文的跟踪管理机制。

      跟踪管理又可以有两条路,一种是采用建立资源池方式,这种是比较正统合理的方案,但我相信AEF将来会改进的。所以我目前采用了第二种方式:实体上下文与HttpContext绑定,并在Application_EndRequest事件中执行清理。

      实体上下文构造函数:

            public DBContext()
            {
                var items = HttpContext.Current.Items;
                items["dbContext" + items.Count] = this;
            }
    

      Global.asax中的函数:

            void Application_EndRequest(object sender, EventArgs e)
            {
                foreach (var item in this.Context.Items.Values)
                {
                    var disposableObj = item as IDisposable;
                    if (disposableObj != null) disposableObj.Dispose();
                }
            }
    

      这个问题一波三折,困扰了两个月。虽然看上去很简单地解决了,但是还是不太爽,没更多时间和能力研究更深层的东西了。Visual Studio 2010发布会上一句口号是:Coding完美世界,很多时候,完美其实是只是一个传说。

  • 相关阅读:
    Aria2任意文件写入漏洞
    webpack添加node_path不是('webpack' 不是内部或外部命令,也不是可运行的程序或批处理文件?)
    闭包的7种形式
    首页 多级展示
    velocity模板入门
    AngularJs 时间控件
    mybatis按时间条件搜索
    数据结构之线性表(双向循环链表)
    数据结构之线性表(链表)
    数据结构之线性表(顺序表)
  • 原文地址:https://www.cnblogs.com/XmNotes/p/2011976.html
Copyright © 2011-2022 走看看