zoukankan      html  css  js  c++  java
  • entity framework 去缓存

    MSDN上对MergeOption枚举的定义为:

    成员名称
    说明

    AppendOnly
    不会从数据源加载对象上下文中已存在的对象。这是查询或调用 EntityCollection<(Of <(TEntity>)>)Load 方法时的默认行为。

    OverwriteChanges
    对象始终从数据源进行加载。数据源值会重写在对象上下文中对对象所做的任何属性更改。

    PreserveChanges
    当一个对象存在于对象上下文中时,不会从数据源加载该对象。保存在对象上下文中对对象所做的任何属性更改。

    NoTracking
    对象保持为 Detached 状态,也不在 ObjectStateManager 中进行跟踪。

    描述的很含糊,所以我做了个简单的测试。

    1、随便查询一个实体对象出来,使ObjectContext中存在该实体对象的缓存。

    2、修改该实体对象属性,使其成为Modified状态

    2、使用断点在查询后暂停程序

    3、去数据库修改这条数据

    4、分别以GetObjectByKey、Where()以不同的MergeOption方式对重新查询该条数据。情况分别如下:

    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的意思是,如果对象属性被修改过,则保留修改记录,否则从数据库直接获取数据

     

    解决办法:重写MergeOption为NoTracking

    方法一:永久设置实体集MergeOption为NoTracking

    ?

    1

    ctx.BasicInfoEntities.MergeOption = MergeOption.NoTracking;

    方法二:只设置该次调用为NoTracking

    ?

    1

    string flowCode=ctx.BasicInfoEntities.Execute(MergeOption.NoTracking).Where(x=>x.UIID==tempGuid).FirstOrDefault().FlowCode;

  • 相关阅读:
    选择器的用处
    全栈工程师基础知识与笔记
    9.13日笔记
    9.12笔记
    9.11Css
    学习笔记
    9.10HTLM
    redis和memcached的区别(总结)
    OO第四次博客作业
    OO第三次博客作业
  • 原文地址:https://www.cnblogs.com/suizhikuo/p/3292477.html
Copyright © 2011-2022 走看看