• 再议在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完美世界,很多时候,完美其实是只是一个传说。

  • 相关阅读:
    快速傅里叶变换(FFT)
    【BZOJ】1005: [HNOI2008]明明的烦恼(prufer编码+特殊的技巧)
    【BZOJ】1030: [JSOI2007]文本生成器(递推+ac自动机)
    cf490 C. Hacking Cypher(无语)
    高精度模板2(带符号压位加减乘除开方封包)
    【BZOJ】1004: [HNOI2008]Cards(置换群+polya+burnside)
    【BZOJ】1500: [NOI2005]维修数列(splay+变态题)
    【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)
    【BZOJ】1052: [HAOI2007]覆盖问题(贪心)
    【BZOJ】1028: [JSOI2007]麻将(贪心+暴力)
  • 原文地址:https://www.cnblogs.com/XmNotes/p/2011976.html
Copyright © 2020-2023  润新知