1. NoTracking() 对查询的更改跟踪使用
1.1 首先了解下MergeOption
1.2 禁用跟踪查询的方法
2. EF中的上下文
2.1 上下文管理
3. EF缓存计划
4. Sql server执行计划缓存
5. 动态创建和懒惰加载
5.1 动态创建Configuration .ProxyCreationEnabled
5.2 懒惰加载Configuration. LazyLoadingEnabled
NoTracking() 对查询的更改跟踪使用
首先了解下MergeOption
是ObjectContext管理查询返回的实体四种方式,他们分别是:
1.AppendOnly——如果要获取的实体在上下文里面,就直接从上下文里面取到,如果不在的话就把取出来的实体附加到上下文里面,这个是默认的方式,这种方式的好处就是会首先从内存里面找你要的实体,比较快。
2.NoTracking——上下文不存实体,这种方式就是说每次都从数据库里面取数据。
3.OverwriteChanges——如果要获取的实体在上下文中,那么该实体的值会被数据库的值覆盖,然后再返回,如果不在的话就把取出来的实体附加到上下文里面。
4.PreserveChanges——如果要获取的实体在上下文中,那么该实体中被用户修改的属性保持不变,其余的属性用数据库的值覆盖,如果不在的话话就把取出来的实体附加到上下文里面。
默认条件下不会禁用对查询的更改跟踪
禁用跟踪查询的方法
1.在使用 DbContext 时禁用对查询的更改跟踪
2.使用 ObjectContext 在查询层面上禁用更改跟踪, Lamdba表达式用过Select后不用再. NoTracking()
3.使用 ObjectContext 禁用对整个实体集的更改跟踪
context.Products.MergeOption = MergeOption.NoTracking;
var productsForCategory = from p in context.Products
where p.Category.CategoryName ==selectedCategory
selectp;
注意,尽管如此,禁用更改跟踪将有效关闭对象缓存。当查询实体时,我们无法通过从 ObjectStateManager 中拉出先前具体化的查询结果来跳过具体化。如果要在相同上下文中重复查询同一实体,启用更改跟踪实际上可提高性能。
中的上下文
在对EF实体进行关系操作的时候,第一步需要我们创建上下文实例对象,然后根据实体的变化进而通过上下文对该实体进行状态的修改,我的理解就是上下文就是一个状态容器,里面可以放好多变化实体,而且还有一种状态标准,比如:增加、删除、修改、查询等状态。然后上下文根据进来实体的变化生成带有状态的可执行脚本然后去操作数据库,从而达到通过EF框架,可以操作数据库的目的。
上下文管理
1.每次创建实例新建一个上下文:
A方法
2.在函数中用using()创建:
B方法
3.创建一个静态方法调用上下文
C方法
调用方法C
每次调用先检测是否存在上下文(Dbcontext),如果存在直接返回,若失效则新建一个上下文,并存储起来命名为(Dbcontext)
3. EF缓存计划
总结:上下文管理A方法和B方法差别不是太大,C方法可减少每次创建上下文的开消,安全方面暂不讨论。APPDomain中的的 ObjectContext 实例间共享查询计划缓存,所以无论用以上哪种方法,程序启动首次查询都比较慢,执行过查询后启用了查询计划缓存,再次查询就快很多。
执行计划缓存
执行一次查询后,SQLserver会把执行计划缓存下来。首次执行查询,
利用SQLserverProfiler跟踪到执行的sql语句
清空跟踪窗口,再次执行的时候,SQLserverProfiler跟踪不到执行的sql语句
可利用DBCC FREEPROCCACHE --删除计划高速缓存中的元素
再次执行查询,SQLserverProfiler就能跟踪到执行的sql语句了
动态创建和懒惰加载
动态创建Configuration .ProxyCreationEnabled
获取或设置一个值,该值指示框架在创建实体类型的实例时是否会创建动态生成的代理类的实例。请注意,即使使用此标记启用了代理创建,也只会为满足代理设置要求的实体类型创建代理实例。默认情况下启用代理创建。
懒惰加载Configuration. LazyLoadingEnabled
获取或设置一个值,该值指示是否启用针对公开为导航属性的关系的延迟加载。延迟加载在默认情况下处于启用状态。
我们会使用这两个设置来决定是否加载导航属性。默认情况这两个值都是true的,也就是说会以延迟加载的方式加载导航属性,
也就是当我们访问导航属性的时候才会去查数据库获取导航属性的数据。
db.Configuration.ProxyCreationEnabled = true ;
db.Configuration.LazyLoadingEnabled = true ;
想禁用加载实体的导航属性,可以这样设置:
db.Configuration.ProxyCreationEnabled = true ;
db.Configuration.LazyLoadingEnabled = false;
或者直接:
db.Configuration.ProxyCreationEnabled = false;
需要注意的是,当ProxyCreationEnabled =false的时候,LazyLoadingEnabled 是不起作用的。