EF数据操做比较详解

1.数据Load

延迟加载:当实体第一次读取时,相关数据没有加载;当第一次试图访问导航属性时,所需的导航数据自动加载,EF默认使用这种方式加载数据,尽可能使用预先加载和显示加载。sql

优势:加载数据快数据库

缺点:数据库交互屡次缓存


预先加载:当读取实体时,相关数据同时读取。这一般会致使一个链接查询,查询全部所需的数据,使用Include方法指定预先加载。服务器

优势: 数据库交互少框架

缺点:加载实体多,数据量大时,变慢,会有不少冗余字段性能


显示加载:这种加载方式相似于延迟加载,不一样的是咱们要在代码中明确地查询相关数据,导航属性是手动控制的,须要调用Collection.Load方法获取集合,调用Reference.Load方法获取单个实体来加载相关数据。优化

优势: 加载数据快,导航属性如何加载能够本身控制,一般关联实体集合的数量被限制时,使用Load方法翻译

缺点: 须要本身控制,数据库交互屡次,交互次数由本身控制设计


CompiledQuery:提供对查询的编译和缓存以供从新使用。当相同的查询须要执行不少遍的时候,那么咱们可使用ComplieQuery将查询的语句进行编译以便下次使用,这样能够免去对同一语句的屡次处理,从而改善性能code

优势:减小查询表达式树编译次数


AsNoTracking:若是数据是只读操做,用AsNoTracking取消追踪,提高性能。

SqlQuery:对于复杂的查询或存储过程的使用,考虑用SqlQuery操做原生sql。

Skip:分页在数据库中分页,不要再内存中分页,以提高性能


IQueryableIEnumerableIQueryable返回的是查询表达式,也就是说生成了SQL查询语句可是却尚未与数据库进行交互。IEnumerable则是已经执行查询数据库的操做且数据保存在了内存中,因此在进行条件拼接的时候必定要在IQueryable类型后面追加Where条件语句,而不是等到ToList以后再开始写条件,以提高性能。

2. 数据Get

Find()方法:查找一个实体,不只查询数据库,并且还查询新添加的没有保存到数据库中的对象。

查找方式:内存查找->新添加还没保存到数据库中的对象->数据库中还没加载到内存中实体

优势:根据主键查找,主键有索引,速度快

缺点:只能根据主键查找


GetObjectByKey()方法:查找一个实体

查找方式:内存查找- >数据库中实体

优势:先从内存中取速度快

缺点:只能根据主键查找,查询不到抛出异常

TryGetObjectByKey()方法:查找一个实体

查找方式:内存查找- >数据库中实体

优势:先从内存中取速度快 , 查询不到返回null

缺点:只能根据主键查找


Single()方法:查找一个实体

查找方式:数据库中实体

优势:不根据主键进行查询或查询时加载相关实体

缺点:查询没有返回结果或返回的结果多于一个就会抛出异常


SingleOrDefault()方法:查找一个实体

查找方式:数据库中实体

优势:不根据主键进行查询或查询时加载相关实体, 查询没有返回结果返回null

缺点:返回的结果多于一个就会抛出异常


First()方法:查找一个实体,不关心是否有多个结果,仅仅取得第一条

查找方式:数据库中实体

优势:不根据主键进行查询或查询时加载相关实体, 只取第一条

缺点:查询没有结果就会抛出异常


FirstOrDefault()方法:查找一个实体,不关心是否有多个结果,仅仅取得第一条

查找方式:数据库中实体

优势:不根据主键进行查询或查询时加载相关实体, 只取第一条,查询没有结果返回null

缺点:不知道是否有多条数据

3.其它优化

事物的简短性:尽可能把查询语句和影响事物的语句放在事物外面执行,防止资源死锁。

批量修改:尽可能用sql执行

预生成视图:在实体框架能够针对概念模型执行查询或将更改保存到数据源以前,它必须生成一组本地查询视图才能访问数据库。 因为生成这些视图会产生很高的成本,所以,您能够在设计时预生成视图并将它们添加到项目。预生成视图方式参考:

https://msdn.microsoft.com/zh-cn/library/bb896240.aspx


AsEnumerable()ToList():二者都是延迟执行sql,区别是AsEnumerable()在执行过滤以前,先将全部数据放到内存中,再进行筛选;ToList()则是先拼接成sql再请求数据库,而后结果放入内存,是真正的筛选数据。


IQueryableIEnumberableIQueryable实现了IEnumberable接口,IEnumerable<T> 泛型类在调用本身的SKipTake 等扩展方法以前数据就已经加载在本地内存里了,IEnumerable跑的是Linq to Object,强制从数据库中读取全部数据到内存先,而IQueryable<T> 是将Skip ,Take 这些方法表达式翻译成T-SQL语句以后再向SQL服务器发送命令,它并非把全部数据都加载到内存里来才进行条件过滤。

相关文章
相关标签/搜索