MSDN上对MergeOption枚举的定义为:
成员名称 | 说明 | |
---|---|---|
| AppendOnly | 不会从数据源加载对象上下文中已存在的对象。这是查询或调用 EntityCollection<(Of <(TEntity>)>) 的 Load 方法时的默认行为。 |
| OverwriteChanges | 对象始终从数据源进行加载。数据源值会重写在对象上下文中对对象所做的任何属性更改。 |
| PreserveChanges | 当一个对象存在于对象上下文中时,不会从数据源加载该对象。保存在对象上下文中对对象所做的任何属性更改。 |
| NoTracking | 对象保持为 Detached 状态,也不在 ObjectStateManager 中进行跟踪。 |
描述的很含糊,所以我做了个简单的测试。
1、随便查询一个实体对象出来,使ObjectContext中存在该实体对象的缓存。
2、修改该实体对象属性,使其成为Modified状态
2、使用断点在查询后暂停程序
3、去数据库修改这条数据
4、分别以GetObjectByKey、Where()以不同的MergeOption方式对重新查询该条数据。情况分别如下:
AppendOnly
OverwriteChanges
该状态下,GetObjectByKey获取到的依然是ObjectContext上的副本(携带Modified状态),但使用Where语句后,三个语句查出来的对象都被更改为数据库当前实际数据,状态。即,使用OverwriteChanges枚举调用Where语句,取出数据会覆盖当前ObjectContext上的数据以及关联的这些副本。
NoTracking
该状态相对比较简单,Where语句直接从数据库获取数据,并且状态为Detached,也不影响ObjectContext中的对象。
PreserveChanges
该状态可能是最难理解的。第一次测试时,发现类似于AppendOnly枚举,执行完后,三个语句查出来的对象都是在ObjectContext中Modified状态的原对象,可能没有访问数据库,我就奇怪那他和AppendOnly有什么区别呢?于是我把修改对象属性的那行代码注释掉后,也就是在ObjectContext中的对象状态为Unchanged,再去执行GetObjectByKey和Where()语句,这时候就发生变化了:Where语句直接取到了数据库中最新的数据,并把ObjectContext以及相关联的对象副本都进行了更新。
因此,PreserveChanges的意思是,如果对象属性被修改过,则保留修改记录,否则从数据库直接获取数据