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的性能改善和思考的更多相关文章

  1. 你是否还在质疑EF的性能

    1. 写在前面的话 一直没有写博客的习惯,感觉太浪费时间,没有那么多精力,其实仔细一想,写博客是一种习惯,也是一种心境,同时也是对自己所掌握的知识结构的一个梳理过程,对自己知识体系的一个巩固,同时也是 ...

  2. C#实用杂记-EF全性能优化技巧

    原文链接:http://www.makmong.com/947.html#comment-31 EntityFramework 优化建议 2016年1月15日 下午4:54 LEILINKANG   ...

  3. 第八节: EF的性能篇(一) 之 EF自有方法的性能测试

    一. 开发中常见的性能问题 我们在日常开发过程中,由于一些不好的习惯,经常会导致所写的代码性能低下,却毫无发觉,下面就总结一下常见的一些性能问题. 1. 真假分页 ① 假分页: db.xxx.toLi ...

  4. 第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题

    一. 综述 该模块主要介绍:EF的性能优化插件Z.EntityFramework.Extensions,该插件收费. (一). 简介 1. 相关网站:http://www.zzzprojects.co ...

  5. MVC教程--MiniProfiler.EF监控调试MVC和EF的性能

    上一篇谈到mvc中ef输出执行sql日志:来谈用mvc开发项目的调试和性能监控.EF框架自动给我生成sql语句,当我们的程序遇到性能问题的时候我们可以用MiniProfiler.EF来监控调试MVC和 ...

  6. try catch引发的性能优化深度思考

    关键代码拆解成如下图所示(无关部分已省略): 起初我认为可能是这个 getRowDataItemNumberFormat 函数里面某些方法执行太慢,从 formatData.replace 到 une ...

  7. 讨论过后而引发对EF 6.x和EF Core查询缓存的思考

    前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...

  8. EF提高性能

    实体框架 5 性能注意事项 作者:David Obando.Eric Dettinger 等 发布时间:2012 年 4 月 1.简介 对象关系映射框架是一种在面向对象的应用程序中提供数据访问抽象的便 ...

  9. 性能改善之For与Foreach

    关于For与Foreach的区别,博客园里已经有好多这样文章了,都分析的挺好:http://www.cnblogs.com/jobs/archive/2004/07/17/25218.aspx  不过 ...

随机推荐

  1. C/C++源代码从写完到运行发生了什么

    有时候经常听到一些不明觉厉的词语,什么编译啊链接啊语义分析啊的,就找书来看看,把笔记画成了图: 编译器干了些啥呢,如下图: 参考书:<程序员的自我修养——链接.装载与库>,<深入理解 ...

  2. css设置背景图片

    background:pink;图片在背景图上面 background-image:url(food.jpg);一张图片铺满一行background-repeat:repeat-x;同一张图片多张铺满 ...

  3. java中一些定时器的使用

    一:简单说明 ScheduleExecutorService接口中有四个重要的方法,其中scheduleAtFixedRate和scheduleWithFixedDelay在实现定时程序时比较方便. ...

  4. Web自动化测试工具调研

    背景 Web自动化测试越来越被重视, 因为现在Web已经是工程化的状态. 如何通过工具测试, 保证Web开发的质量,提升开发效率,是Web工具的诞生的来由. Web测试分为以下几个方面: 1. 界面测 ...

  5. fopen,fread和fwrite

    在最近的编程练习和写东西的过程中,常常用到了fopen和fread两个函数来读取本地文件.之前使用这两个函数时,一直没有出现过什么问题.也是因为没有出现问题,对这两个函数的用法的一些细节没有很了解,所 ...

  6. KEEPALIVED 双机自动切换部署备忘

    1.配置文件的名字不要型错了.开始我将配置文件写成keeplive.conf,运行后也不报错,但无法看到VIP.日志里也看不到任何有价值信息.直到后来反复检查才发现可能配置文件名有问题,修正为keep ...

  7. Linux中可用于管道操作的命令总结

    在Linux中药进行稍复杂的操作,通常需要借助管道命令"|"多个命令的组合,形式如下: command 1 |  command 2 |  command 3 -- 在linux中 ...

  8. UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  9. Android -- OkHttp的简单使用和封装

    1,昨天把okHttp仔细的看了一下,以前都是调用同事封装好了的网络框架,直接使用很容易,但自己封装却不是那么简单,还好,今天就来自我救赎一把,就和大家写写从最基础的OKHttp的简单get.post ...

  10. Android仿“守望先锋”加载动画

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 效果图 实现思路 画一个小六边形 按效果图位置画七个小六边形 实现一个小六边形的显示与隐藏 ...