EF的性能改善和思考
EF是个工具,用的好了性能就会很好,用的不好性能就会有很大损失。
先从EF的设计思想来讲解
EF的初衷是根据缓存中的实体对象,以及实体对象的状态(删除、更新、添加)来对数据库进行操作,这些实体对象、以及对象的状态都是在一个对象上下文ObjectContext中进行维护的,数据上下文DbContext显式实现了IObjectContextAdapter接口。DbContext在最后SaveChanges提交的时候,会调用ObjectContext的SaveChanges, 将所有更新保存到数据库并重置对象上下文中的更改跟踪。所以DbContext是对ObjectContext进行的二次封装和完善。
1.EF的初衷是好的,避免对数据库频繁的提交,先操作实体对象,直到实体对象不需要再更改了,最后提交的时候再将所有更新保存到数据库。但是凡事都是相对的,如果维护了大量的实体会使内存消耗很大,所以怎么办呢,应该尽量避免不必要的缓存实体,譬如纯粹的查询,EF在查询的时候可以使用AsNoTracking()避免将查询的实体或者实体序列放在缓存中,这在很大程度可以节省了内存。
2.EF鼓励将多个操作放在一个数据上下文中,所以有人说采用EF不需要DAL层了,可以直接在业务层包装using(DbContext=new DbContext()){},然后对数据库做各种表的操作,这个是没问题的,但是在开发中,这样做效率会很低,会写很多重复代码,举个简单的例子,假如一个条件查询,如果有DAL层的封装方法,我就可以在业务层方便的调用,避免每次都去想着怎么去组装条件进行查询,所以DAL层对于开发效率来说还是必要的,如果需要DAL层就要考虑数据仓储类的实现,数据仓储类该如何实现呢?
3.数据仓储类,数据仓储类封装了通用的针对数据库的单元操作方法,封装这些方法中应该避免使用using(DbContext=new DbContext()){}包装单元操作,EF的设计初衷是什么?避免频繁的与数据库进行交互,如果采用这种方式封装单元操作,一个单元操作使用一个数据上下文,那么EF的性能优势在哪里?另外采用这种方式封装,EF的“本地事务”也被破坏了,已经毫无”事务”可言,所以数据仓储类可以采用一个临时公用的数据上下文,比如你将数据上下文放在线程对象中,这里的事务我加了一个引号,因为EF在提交的时候根据对象上下文来更新数据库的,所以最后一次提交之前,实际上并没有和数据库交互,数据上下文提交的时候,会进行事务的封装,如果失败了,本次提交的所有操作回滚。
4.EF的初衷是想维护一个完整性的对象上下文,但是实际生产中很难做到,比如执行了一个sqlcommand更新了一个字段,但是对象上下文中的该属性没有被更新,所以也许会说,采用EF就避免使用sql进行操作了,但是Dbcontext留下了DataBase口子,public int ExecuteSqlCommand(string sql, params object[] parameters);留下了口子,就避免不了会被采用,所以更稳妥的做法是采用DbContextTransaction来控制事务,而不是单纯地依靠SaveChanges,另外如果采用了ExecuteSqlCommand,一旦破坏了数据对象的完整性,再进行更新操作的时候很可能会覆盖掉之前执行的操作,那么怎么办呢,解决办法有两个,1.根据字段进行更新,而不是更新整个实体2.将数据对象分离,重新附加,然后更新,很明显1的方法性能更好
5.如何Dispose掉Dbcontext?首先要清楚Dispose是干什么的,Dispose是为了释放资源,不是销毁对象,销毁对象是谁干的,销毁对象是GC干的,GC准备销毁对象的时候,会检查对象有么有析构函数,如果有会将这些对象升级暂不销毁,直到全部执行完析构,在下次回收的时候再销毁掉,可是Dbcontext没有析构函数,但是Dbcontext是对ObjectContext的二次封装和完善,ObjectContext实现了析构,所以如果Dbcontext没有显示的去Dispose,GC回收数据上下文对象的时候,会升级该对象,直到所有的析构执行完毕,在下次回收的时候再一并销毁掉。我们不知道垃圾回收的具体时间,但是显示的Dispose可以减少Dbcontext对象的生命周期。所以在应用程序中,我们可以在请求结束的最后,执行显示的Dispose,譬如对于mvc、webapi程序,可以在过滤器中,请求结束的时候执行Dispose操作,对于asp.net可以在basepage中进行Dispose操作。
//
// 摘要:
// 由可提供 System.Data.Entity.Infrastructure.IObjectContextAdapter.ObjectContext 实例的对象实现的接口。System.Data.Entity.DbContext
// 类实现此接口以提供对基础 ObjectContext 的访问。
public interface IObjectContextAdapter
{
//
// 摘要:
// 获取对象上下文。
//
// 返回结果:
// 对象上下文。
ObjectContext ObjectContext { get; }
}
//
// 摘要:
// DbContext 实例表示工作单元和存储库模式的组合,可用来查询数据库并将更改组合在一起,这些更改稍后将作为一个单元写回存储区中。DbContext 在概念上与
// ObjectContext 类似。
public class DbContext : IDisposable, IObjectContextAdapter
{
//
// 摘要:
// 将在此上下文中所做的所有更改保存到基础数据库。
//
// 返回结果:
// 已写入基础数据库的对象的数目。
public virtual int SaveChanges();
EF的性能改善和思考的更多相关文章
- 你是否还在质疑EF的性能
1. 写在前面的话 一直没有写博客的习惯,感觉太浪费时间,没有那么多精力,其实仔细一想,写博客是一种习惯,也是一种心境,同时也是对自己所掌握的知识结构的一个梳理过程,对自己知识体系的一个巩固,同时也是 ...
- C#实用杂记-EF全性能优化技巧
原文链接:http://www.makmong.com/947.html#comment-31 EntityFramework 优化建议 2016年1月15日 下午4:54 LEILINKANG ...
- 第八节: EF的性能篇(一) 之 EF自有方法的性能测试
一. 开发中常见的性能问题 我们在日常开发过程中,由于一些不好的习惯,经常会导致所写的代码性能低下,却毫无发觉,下面就总结一下常见的一些性能问题. 1. 真假分页 ① 假分页: db.xxx.toLi ...
- 第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题
一. 综述 该模块主要介绍:EF的性能优化插件Z.EntityFramework.Extensions,该插件收费. (一). 简介 1. 相关网站:http://www.zzzprojects.co ...
- MVC教程--MiniProfiler.EF监控调试MVC和EF的性能
上一篇谈到mvc中ef输出执行sql日志:来谈用mvc开发项目的调试和性能监控.EF框架自动给我生成sql语句,当我们的程序遇到性能问题的时候我们可以用MiniProfiler.EF来监控调试MVC和 ...
- try catch引发的性能优化深度思考
关键代码拆解成如下图所示(无关部分已省略): 起初我认为可能是这个 getRowDataItemNumberFormat 函数里面某些方法执行太慢,从 formatData.replace 到 une ...
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
- EF提高性能
实体框架 5 性能注意事项 作者:David Obando.Eric Dettinger 等 发布时间:2012 年 4 月 1.简介 对象关系映射框架是一种在面向对象的应用程序中提供数据访问抽象的便 ...
- 性能改善之For与Foreach
关于For与Foreach的区别,博客园里已经有好多这样文章了,都分析的挺好:http://www.cnblogs.com/jobs/archive/2004/07/17/25218.aspx 不过 ...
随机推荐
- http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/index.html
http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/index.html
- visual studio code 里调试运行 Python代码
最近对微软的visual studio code 挺感兴趣的,微软的跨平台开发工具.轻量简洁. 版本迭代的也挺快的,截止16年8月2日已经1.3.1版本了,功能也愈加完善.(16年12月18日 已经, ...
- 怎么搭建DC+SCCM 域环境(一)
需要的软件: 1. SCCM 2012 SP1 2. SQL Server 2012 3. System ISO 4. ADK 环境搭建顺序: 1. 安装DC和SCCM 机器,并配置需要的IP.DNS ...
- zabbix agent安装与配置篇
Zabbix监控windows部署安装 Zabbix agent 在windows上安装部署 (1)手工安装zabbix agent客户端 1. 下载与解压 地址: http://www.zabb ...
- 【尝新】微信小程序初体验
文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/?t=1474644089434 根据文档地址中下载微信开发工具后,按照文档指引可以创建一个快速体验的小d ...
- 4,4s屏幕过渡页处理
//#import "sys/utsname.h" struct utsname systemInfo; uname(&systemInfo); NSString *dev ...
- lkx开发日志1-项目前的准备
遇到的问题 不了解github的使用 不能熟练的用Markdown编辑,比如:放入图片 虚拟机的认知也还是有点模糊 解决的方法 参照老师博文给出的链接,好好学习实操一遍 多请教组员,很多小问题便迎刃而 ...
- Java 中 ThreadLocal 内存泄露的实例分析
前言 之前写了一篇深入分析 ThreadLocal 内存泄漏问题是从理论上分析ThreadLocal的内存泄漏问题,这一篇文章我们来分析一下实际的内存泄漏案例.分析问题的过程比结果更重要,理论结合实际 ...
- Computop支付网关(一) credit Card
1.界面没有中文,只能选择英文 sp – Spanish; en – English; ca – Catalan; fr – French; de – German; du – Dutch; it – ...
- oracle归档模式和非归档模式的切换
Oracle从未归档日志改成归档日志: SQL> shutdown immediate; 数据库已经关闭. 已经卸载数据库. Oracle 例程已经关闭. SQL> startup mou ...