为了账号安全,请及时绑定邮箱和手机立即绑定

linq to sql中的自动缓存(对象跟踪)

标签:
前端工具

这篇东西应该至少一年前就写的,不过因为个人太懒,一直没记下来,今天补上.

linq to sql中,对于同一个DataContext上下文环境,根据表主键选择记录时(当然这里所指的“记录”会自动转成“对象”),如果该记录已经被select过,默认情况下会被自动缓存下来,下次再选择时,将自动返回已缓存的对象,而不是重新从数据库里查询。

 

在很多情况下(特别是查询的场景),这会提高性能(因为避免了数据库重复查询),但是也时候也会带来麻烦:

 

比如我们取出一个对象后,对其属性做了修改,然后提交到数据库前,想比较一下原始记录,如果某些属性修改过了,则这样处理,如果未被修改过,则那样处理。因为缓存的关系,我们重新取出原始记录时,其实取出的并不是数据库中的原始值,而缓存在内存里的对象实例(即修改后的对象 ),所以比较时,永远都会返回未修改过。

 

测试原始记录如下:

 

测试代码如下:

using System;

using System.Linq;

using System.Diagnostics;

 

namespace webApp

{

    public partial class Default : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            dbDataContext db = new dbDataContext();            

 

            var u1 = db.Users.FirstOrDefault(c=>c.Id==1);          

            u1.Photo = "new value";//这里修改了用户的头象

 

            var u2 = db.Users.FirstOrDefault(c => c.Id == u1.Id);//重新查询原始值            

 

            if (u2.Photo == u1.Photo)

            {

                Debug.WriteLine("用户头象未被修改!");

            }

            else

            {

                Debug.WriteLine("用户头象被修改过了!");

                //to do list...

                //如果保存到数据库,还应该删除原来的旧头象

            }

        }

    }

}

如果运行一下,将永远得到的都是"用户头象未被修改!"。

 

解决办法有二个:

1、关闭默认的对象跟踪

即:

1

2

dbDataContext db = new dbDataContext()

;db.ObjectTrackingEnabled = false;//关闭默认的对象跟踪

这个办法最简单,但却是一刀切的办法,会关闭db所有的缓存功能,在查询请求远大于更新请求的场景下,个人并不太喜欢。

 

2、创建一个新的DataContext上下文来查询原始值

即:把u2的取值部分改为

?

1

2

3

4

5

6

User u2 = null; 

using (dbDataContext db2 = new dbDataContext()) //创建一个新的上下文

{       

 u2 = db2.Users.FirstOrDefault(c => c.Id == u1.Id);//重新查询原始值  


}

临时创建一个db2,然后用它来重新查询原始值,由于db2是刚创建,之前肯定没有查询过Id==u1.id的记录,所以缓存是空的,因此会到数据库重新查询,当然db2用完后,会自动释放相关资源(using的功劳!) 

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消