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

简介: 这篇东西应该至少一年前就写的,不过因为个人太懒,一直没记下来,今天补上.   linq to sql中,对于同一个DataContext上下文环境,根据表主键选择记录时(当然这里所指的“记录”会自动转成“对象”),如果该记录已经被select过,默认情况下会被自动缓存下来,下次再选择时,将自动返回已缓存的对象,而不是重新从数据库里查询。
+关注继续查看

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

 

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

 

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

 

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

 

测试原始记录如下:

img_e6de8675100eeda986f9fd7010ce94ab.png

 

测试代码如下:

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

目录
相关文章
|
2月前
|
SQL 存储 缓存
SQl Server——ADO.NET五大对象
在某些编程中总是会需要用到数据库,那如何让应用程序和数据库之间建立联系呢?ADO.NET就提供了应用程序连接数据库的桥梁
|
4月前
|
SQL
GBASE8s大对象sql语句使用
GBASE8s大对象sql语句使用
|
SQL Java 数据库连接
hibernate自定义sql关联查询结果组装为对象
hibernate自定义sql关联查询后没有对应的entity,如何映射为对应的bean
172 0
|
安全 数据安全/隐私保护 云安全
高危预警| SQL数据库成主要攻击对象,或引发新一轮大规模勒索
云安全中心已提供免费7天试用服务,登陆控制台开启企业版试用功能,利用漏洞修复、基线检查、安全告警功能对系统做深度检查,及时修复当前存在的安全隐患。
14026 0
|
SQL 关系型数据库 数据库
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 5 章 数据定义_5.12. 其他数据库对象
5.12. 其他数据库对象 表是一个关系型数据库结构中的核心对象,因为它们承载了我们的数据。但是它们并不是数据库中的唯一一种对象。有很多其他种类的对象可以被创建来使得数据的使用和刮泥更加方便或高效。
966 0
|
SQL 存储 Go
SQL Server修改数据库对象所有者(Owner)浅析
原文:SQL Server修改数据库对象所有者(Owner)浅析 在SQL Server数据库中如何修改数据库对象(表、视图、存储过程..)的所有者(Owner)呢?一般我们可以使用系统提供的系统存储过程sp_changeobjectowner来修改。
1336 0
|
SQL 存储 Go
SQL Server中授予用户查看对象定义的权限
原文:SQL Server中授予用户查看对象定义的权限 SQL Server中授予用户查看对象定义的权限   在SQL Server中,有时候需要给一些登录名(用户)授予查看所有或部分对象(存储过程、函数、视图、表)的定义权限存。
869 0
|
SQL Go 数据库
在SQL Server中查看对象依赖关系
原文 在SQL Server中查看对象依赖关系 Viewing object dependencies in SQL Server   Deleting or changing objects may affect other database objects like views or ...
1463 0
|
SQL 数据库
如何快速搜索SQL数据库数据和对象
原文 如何快速搜索SQL数据库数据和对象 Frequently, developers and DBAs need to search databases for objects or data. If you’d ever searched for a database function tha...
985 0
|
SQL Oracle 关系型数据库
sql developer Oracle 数据库 用户对象下表及表结构的导入导出
Oracle数据库表数据及结构的导入导出   导出的主机与即将导入到的目标主机的tablespace 及用户名需一直!!!!!  
1755 0
推荐文章
更多