linq to sql中的自动缓存(对象跟踪)
时间:2022-04-23
本文章向大家介绍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、关闭默认的对象跟踪
即:
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的功劳!)
- Android自定义 View 实战之 StickerView
- 十分钟搞定酷炫动画,Android自定义 View 入门
- 基础篇章:关于 React Native 之 Switch 和 ProgressBarAndroid 组件的讲解
- Android 实现视屏播放器、边播边缓存功能、外加铲屎(IJKPlayer)
- 基础篇章:关于 React Native 之 ToolbarAndroid 组件的讲解
- Android M 权限最佳实践
- Android自定义ViewGroup神器-ViewDragHelper
- Android 中常见的内存泄漏
- Android 高级自定义Toast及源码解析
- 环境配置:React Native 开发环境配置 For Android
- 美团多渠道打包方案详解,速度快到白驹过隙
- 下一代Android渠道打包工具
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
- 通俗易懂的分析如何用Python实现一只小爬虫,爬取拉勾网的职位信息
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇)
- 树状数据库表查询2次以上(自连接、内连接、别名)方法
- 网页背景H5视频自动播放---PC端、移动端兼容问题完美解决方案(IOS、安卓、微信端)
- 【STM32F407】第11章 RL-TCPnet V7.X之TCP服务器
- 如何解决nodejs中cpu密集型的任务
- 博客园主题1【备份】
- 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇)
- POSTGRESQL 到底怎么访问同instance 的库--
- 简单工厂模式
- 这 9 种方法有效帮你提高国内访问 Github 的速度
- python实现sm2和sm4国密(国家商用密码)算法
- 面试常考算法之区间问题
- 爬虫 | JS逆向某验滑动加密分析
- LeetCode | 28.实现strStr()
- Redis | Redis 哈希相关命令