惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
Cloudbric
Cloudbric
G
GRAHAM CLULEY
S
Securelist
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
Spread Privacy
Spread Privacy
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
T
Tailwind CSS Blog
博客园_首页
有赞技术团队
有赞技术团队
Simon Willison's Weblog
Simon Willison's Weblog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Latest news
Latest news
T
Tor Project blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Attack and Defense Labs
Attack and Defense Labs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
O
OpenAI News
J
Java Code Geeks
T
Tenable Blog
K
Kaspersky official blog
AWS News Blog
AWS News Blog
S
Security @ Cisco Blogs
The GitHub Blog
The GitHub Blog
T
Threatpost
月光博客
月光博客
H
Heimdal Security Blog
Security Latest
Security Latest
The Hacker News
The Hacker News
Y
Y Combinator Blog
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
C
Cisco Blogs
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
C
CERT Recently Published Vulnerability Notes
D
Docker
Google Online Security Blog
Google Online Security Blog
D
DataBreaches.Net
V
Visual Studio Blog
H
Help Net Security

博客园 - 朱小能

C#对Dictionary的按Value排序 javascript 调用webservice 的几种方法 修改域名映射IP地址 SQL 语句,类型转换 hyper-v 网络连接 VS2010 定位文件在solution中的位置 oracle连接字符串配置 spool的简单使用 open数据库Timeout expired 错误 文件的还原与备份 - 朱小能 - 博客园 ASCII码,对应e.KeyChar C# 调用计算器,日历 - 朱小能 - 博客园 Excel 如何由一个文本算术公式得到一个结果 Word、Excel中输入当前日期及时间的快捷键 c# ToString 格式化数字 - 朱小能 GridView绑定 获取access中表的相关信息 Filelog - 朱小能 - 博客园 List<T> 排序 - 朱小能 - 博客园
linq to sql中的自动缓存(对象跟踪)
朱小能 · 2013-04-03 · via 博客园 - 朱小能

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的功劳!) 

出处:http://www.cnblogs.com/yjmyzz/archive/2010/08/24/1807271.html