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

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、关闭默认的对象跟踪

即:

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

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

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

即:把u2的取值部分改为

User u2 = null;using (dbDataContext db2 = new dbDataContext()) //创建一个新的上下文
{u2 = db2.Users.FirstOrDefault(c => c.Id == u1.Id);//重新查询原始值
}

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

linq to sql中的自动缓存(对象跟踪)相关推荐

  1. LINQ TO SQL中还是用传统的连接串方式建立DbContext更好些

        首先,在LINQTOSQL中可以这样建立一个dbcontext      private TEntity GetOriginal(TEntity entity)         {       ...

  2. 在Linq to Sql中管理并发更新时的冲突(3):使用记录的时间戳进行检测

    我们描述了Linq to Sql检测在更新时是否产生了冲突的基本方法:将该记录每个字段原来的值和更新时的值进行对比,如果稍有不同则意味着记录被修改过,因此产生了更新冲突.不过您是否有这样的感觉,这种方 ...

  3. 在LINQ to SQL中使用Translate方法以及修改查询用SQL

    目前LINQ to SQL的资料不多--老赵的意思是,目前能找到的资料都难以摆脱"官方用法"的"阴影".LINQ to SQL最权威的资料自然是MSDN,但是M ...

  4. 浅谈Linq to SQL中的模式

    学习Linq to SQL也有一段时间了,感叹它做为ORM虽然简单但是功能效率都还不错,从编译器和语言层面支持上来看,它是其他ORM工具不能比的.Linq to SQL中运用了很多模式对自身的效率进行 ...

  5. 【转】 LINQ TO SQL中的selectMany

    首先看SelectMany的定义: Queryable中的SelectMany 方法:将序列的每个元素投影到一个 IEnumerable<(Of <(T>)>) 并将结果序列组 ...

  6. java用redis缓存的步骤_详解在Java程序中运用Redis缓存对象的方法|chu

    这段时间一直有人问如何在Redis中缓存Java中的List 集合数据,其实很简单,常用的方式有两种: 1. 利用序列化,把对象序列化成二进制格式,Redis 提供了 相关API方法存储二进制,取数据 ...

  7. 如何在SQL中设置自动编号

    如何在SQL中设置自动编号 关键词: 自动编号    SQL    设置    Nicholas    课程设计 你创建一个表,把其中一个列(比如"ID")的"标识列&q ...

  8. Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式

    当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left ...

  9. linq to sql 中,如何解决多条件查询问题,答案,用表达式树! (下)

    ,我们做了基于linq to sql 的多条件组合查询,但通过监视数据库发现,这样做的成本比较高,每次都要取出全部的数据到内存进行筛选.如何从真正意义上做到延迟加载,即一次只从数据库中取我们需要的用到 ...

最新文章

  1. MongoDB探索之路(二)——系统设计之CRUD
  2. select2的一些特性效果
  3. java 27 - 4 反射之 通过反射获取成员变量并使用
  4. 框架开发之Java注解的妙用
  5. 深入理解ROS技术 【3】ROS下的模块详解(129-180)
  6. spring cloud 定时任务
  7. 信息竞赛进阶指南--搜索相关(模板)
  8. java 拷贝属性值_Java 反射拷贝相同的属性值到指定对象中(两种实现方式)
  9. Oracle中用于发送邮件的存储过程
  10. 移动端日期控件 mobiscroll
  11. 每日英语:6 Brainy Habits of the Wisest People
  12. 【渝粤教育】电大中专药物化学基础作业 题库
  13. VS2013 + Qt 提示 There‘s no Qt version assigned to this project for platform Win32
  14. C盘爆红,一个操作将微信缓存踢走
  15. GPU求解粘性不可压流体
  16. MPC与LQR的详细对比分析
  17. [NOIP2017模拟]permut
  18. Android Studio 制作APP启动界面(Splash)
  19. 计算机一级经验分享,计算机一级考试经验
  20. 萧伯纳学演讲不怕出丑

热门文章

  1. MIT要和世界各地研究机构合作,让机器能像婴儿一样学习
  2. rabbitmq 之 ack
  3. LSTM神经网络输入输出究竟是怎样的?
  4. [COGS2639]偏序++
  5. Oracle11新特性——初始化文件管理
  6. 网页设计师必备的35套图标(免费下载)
  7. HBuilder创建app 基础
  8. DDoS功击的判定方法和防护措施
  9. 你知道吗?macOS Sierra修复漏洞超过60个
  10. [Javascript] Math ceil()、floor()、round()三个函数的区别