Entity Framework中数据缓存的问题
来源:互联网 发布:怎样建淘宝团购微信群 编辑:程序博客网 时间:2024/05/16 11:38
EF通过linq读取数据库数据的时候会在本地对数据进行缓存,以提高效率。如果缓存策略配置不对容易造成EF中返回的数据和DB中数据不同的情况,默认情况下本地已经存在的对象在读取数据库的时候不会进行更新。结觉这个问题的方法有:
1.避免使用全局的DBContext对象,在需要读取数据的时候实例化一个临时的DBContext对象
using (PDSCoreDBContext innerContext = new PDSCoreDBContext())
{
var query = from b in innerContext.DataFileInfoes
where b.FirmId == workflowInstance.SubscriberFirmID && b.WorkflowInstanceId == workflowInstance.WorkflowInstanceId && b.DataFileInfoId > maxDataFileInfoId_Previous
select b;
foreach (DataFileInfo item in query)
{
fileInfoCollection.Add(item);
Console.WriteLine("Count:" + item.DownloadCount);
}
}
2.设置缓存策略(MergeOption):
MSDN:
AppendOnly
不会从数据源加载对象上下文中已存在的对象。这是查询或调用 EntityCollection<(Of <(TEntity>)>) 的 Load 方法时的默认行为。
OverwriteChanges
对象始终从数据源进行加载。数据源值会重写在对象上下文中对对象所做的任何属性更改。
PreserveChanges
当一个对象存在于对象上下文中时,不会从数据源加载该对象。保存在对象上下文中对对象所做的任何属性更改。
NoTracking
对象保持为 Detached 状态,也不在 ObjectStateManager 中进行跟踪。
AppendOnly
该状态下,无论是GetObjectByKey还是Where()都取到的是ObjectContext上的副本(携带Modified状态),没有真正访问数据库(后测试发现确实产生了数据查询,但是获取出来的值依然是上下文副本中的,并且这次查询并不会改变上下文中的CurrentValue和OriginalValue,即便上下文中实体为Modified状态。暂时不知道为什么会是这样的设计结果)。
OverwriteChanges
该状态下,GetObjectByKey获取到的依然是ObjectContext上的副本(携带Modified状态),但使用Where语句后,三个语句查出来的对象都被更改为数据库当前实际数据,状态。即,使用OverwriteChanges枚举调用Where语句,取出数据会覆盖当前ObjectContext上的数据以及关联的这些副本。
NoTracking
该状态相对比较简单,Where语句直接从数据库获取数据,并且状态为Detached,也不影响ObjectContext中的对象。
PreserveChanges
该状态可能是最难理解的。第一次测试时,发现类似于AppendOnly枚举,执行完后,三个语句查出来的对象都是在ObjectContext中Modified状态的原对象,可能没有访问数据库,我就奇怪那他和AppendOnly有什么区别呢?于是我把修改对象属性的那行代码注释掉后,也就是在ObjectContext中的对象状态为Unchanged,再去执行GetObjectByKey和Where()语句,这时候就发生变化了:Where语句直接取到了数据库中最新的数据,并把ObjectContext以及相关联的对象副本都进行了更新。
因此,PreserveChanges的意思是,如果对象属性被修改过,则保留修改记录,否则从数据库直接获取数据
1. Set the value of the EntitySet.MergeOption property
When you do this, any queries you create from the entity set will use the MergeOption value you specify. For example:
this.ObjectContext.EmployeeEntitySet.MergeOption = MergeOption.OverwriteChanges;
IQueryable<EmployeeEntity> query = from e in this.ObjectContext.EmployeeEntitySet
where e.EmployeeID == employeeID
select e;
return query.FirstOrDefault();
2. You can create an object query and set its MergeOption property
When you do this, the setting only applies to the current query. For example:
ObjectQuery<EmployeeEntity> query = this.ObjectContext.CreateQuery<EmployeeEntity>(“[EmployeeEntitySet]”);
query.MergeOption = MergeOption.OverwriteChanges;
var res = from ei n query
where e.EmployeeID == employeeID
select e;
return res.FirstOrDefault();
3. You can convert the IQueryable<T> into an object query, call Execute() and specify the MergeOption
This also sets the MergeOption on a specific query, rather than all queries of that type. For example:
IQueryable<EmployeeEntity> query = from e in this.ObjectContext.EmployeeEntitySet
where e.EmployeeID == employeeID
select e;
ObjectQuery objectQuery = (ObjectQuery)query;
ObjectResult<EmployeeEntity> result = (ObjectResult<EmployeeEntity>objectQuery.Execute(MergeOption.OverwriteChanges);
return result.FirstOrDefault();
把MergeOption设置为“NoTracking”也可以,但效率会下降。
也可直接设置:
var query = from b in PDSCoreDBContextTest.DataFileInfoes.AsNoTracking()
where b.FirmId == workflowInstance.SubscriberFirmID && b.WorkflowInstanceId == workflowInstance.WorkflowInstanceId && b.DataFileInfoId > maxDataFileInfoId_Previous
select b;
- Entity Framework中数据缓存的问题
- entity framework 缓存干扰的数据不一致问题
- entity framework 缓存干扰的数据不一致问题
- entity framework的数据访问
- Entity FrameWork中常用的数据修改方式
- Entity Framework中实体模型命名空间的问题
- Entity Framework中使用SQLite的一些问题
- Entity Framework在WCF中序列化的问题
- Entity Framework在WCF中序列化的问题
- Entity Framework在WCF中序列化的问题 学习
- 关于Entity Framework中自增主键的问题
- Entity Framework在WCF中序列化的问题
- entity framework 数据库默认时间的问题
- Entity Framework中对应于Entity的代理类
- Entity Framework 4中删除所有数据行的几种方法
- Entity Framework 4中删除所有数据行的几种方法
- 在Apworks数据服务中使用基于Entity Framework Core的仓储(Repository)实现
- ADO.NET Entity Framework调用存储过程中碰到的问题
- 明确一下,哪些类型放在data区
- SurfaceView
- Android Studio项目目录结构
- Leetcode #48 Rotate Image
- VFS(虚拟文件系统)
- Entity Framework中数据缓存的问题
- tar.xz文件如何解压
- redis中各种数据类型对应的jedis操作命令
- Dissect Bluedroid From A2DP Part I: Use Case
- UML 基础: 序列图
- HDU 1020 Encoding
- XMPP系列(一):OpenFire环境搭建
- Linux入门
- qrencode二维码生成在linux下的编译