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. VS2012完全卸载与VS2013安装

    项目本来使用的是vs2012 Ultimate,也一直跟随ms的节奏安装了从1到4的update,但一些无法忍受的问题却一直没有解决: 1.偶尔出现要等待编辑器响应的情况: 2.偶尔输入了冒号也不会出 ...

  2. vuejs里封装的和IOS,Android通信模块

    项目需要,在vuejs开发的web项目中与APP进行通信,实现原理和cordova一致.使用WebViewJavascriptBridge. 其实也是通过拦截url scheme,支持ios6往前的系 ...

  3. java 之return

    return关键词有两个用法,一方面制定一个方法返回什么值,另一方面导致当前方法退出.

  4. Java 实现函数回调

    在Java里没用委托(delegate)这方法,所以想要实现回调还是有些麻烦.(想了解C#如何实现?请查看:http://www.cnblogs.com/Martin_Q/p/4478494.html ...

  5. css3的新特性transform,transition,animation

    一.transform css3引入了一些可以对网页元素进行变换的属性,比如旋转,缩放,移动,或者沿着水平或者垂直方向扭曲(斜切变换)等等.这些的基础都是transform属性 transform属性 ...

  6. UIWebView中加载HTML的Table,td设置百分比宽度并且宽度不被里面的内容撑开

    正常情况下,iOS使用WebView加载HTML的Table时,为了让Table适应屏幕宽度,会使用百分比设置td的宽度,但是由于td中的内容过多,td会被撑开,导致整个Table的宽度会变宽,超出屏 ...

  7. vulcan测试记录

    感觉这个游戏很赞,是六个里面最喜欢的一个了 1.有时候挖坑对于位置要求比较大? 2.感觉难度比较大,尤其是玩到第三关很考验啊(不过从另一个方面来说也是优点?) 3.玩到现在对于怪物吃金子的原理没有很懂 ...

  8. linux系统无法启动解决方案

    windows和linux双系统一般先安装Windows,分两个主分区,把Linux安装在另外的主分区上.Linux编译内核,添加NTFS分区支持,然后Mount NTFS 分区即可访问Windows ...

  9. 校内通知-Notifications表增加老师,家长,学生发送范围字段

    老师发送范围:TReceiveRange 家长发送范围:PReceiveRange 学生发送范围:SReceiveRange alter table Notifications add TReceiv ...

  10. XiangBai——【AAAI2017】TextBoxes_A Fast Text Detector with a Single Deep Neural Network

    XiangBai--[AAAI2017]TextBoxes:A Fast Text Detector with a Single Deep Neural Network 目录 作者和相关链接 方法概括 ...