控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

为提高entity framework 性能,要注意哪些事情

作者:未知 出处:cnblog 2013年04月26日 阅读:

 我发现现在有不少博友,都反对使用EF框架,说它性能低.其实只要你用的好,性能不是问题,经过测试,它也会接近ado.net的访问了.

 
       当然如果对EF不了解,随便乱用,确实会引来性能问题.因为EF的查询语句都是自己生成的.如果不注意,它会多次查询数据库,或用效率不高的语句去查询.
 
      下面我就把我们在项目中遇到的问题,现我把他总结出来.以供大家参考.当然还有一些没有列出来的,希望各网友也一起提供一下,以避免大家少走弯路.
 
1.分页的时候,尽量在数据库里面去分页.在我实际中的项目,我就发现我同事由于他不了解EF属性,它的分页都是做在内存中分页.下面请看他的代码. 
         queryToList().Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize);
 
         像上面的语句,他会先把数据从数据库中查出来,然后才分页.
 
          正确的写法应如下:
 
       query.Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize).ToList();这样才会在数据库中分页.
 
     2.尽量禁用延迟加载,尽量使用预加载和显式加载查询.
 
       Vs 默认生成的代码,是启用了延迟加载的.这样往往是有些开发人员在不了解的情况下,进行了多次往数据库查询.如下的代码.
 
        using (SchoolContainer db = new SchoolContainer())
 
        {
 
           var list = db.People.Where(ent => ent.PersonID < 30).ToList();
 
            foreach (var people in list)
 
            {
 
                foreach (var ent in people.StudentGrades)
 
                {
 
                    Console.WriteLine(ent.Grade);
 
                }
 
              }
 
        }
 
 如果启用延迟加载,这样会造成多次往返数据库查询的.势必造成性能低下. 
 
因此我们在这里应该使用预加载.代码如下:
 
var list = db.People.Include("StudentGrades").Where(ent => ent.PersonID < 30).ToList();
 
当然使用了预加载,延迟加载也不会查询多次.但怕在程序员写代码时,忘了要预加载,如果启用了延迟加载,那么就会多次查询数据库.如果不启用,那么程序员就获取不了数据,这样他就马上明白,要进行预加载了.
 
当然任何事情不是绝对的.如果被查询的对象,过于复杂,就要慎用预加载
 
       3.注意事务的简短性.
 
在使用事务时,我们要尽量把查询语句或者其他响事务外的语句移在事务外执行.不然让一个事务的时间太长了,就容易引起资源死锁的问题.我上次就优化我一个同事的代码,他代码里就把所所有不相关的东西都放在事务里执行,这样就造成事务的时间太长,当用压力测时,马上就出现资源被锁的错误.
 
       4.查询出来的实体,如果不考虑删除和修改,请用NoTracking
 
         关于Notracking 的使用方法,请看. http://www.cnblogs.com/LingzhiSun/archive/2011/04/27/EF_Trick4.html
 
       5.批量删除和修改,不要用先把实体查询出来,然后再逐个删除和修改.这样会产生大量的语句,效率肯定会低.
 
对于这个解决方式一是直接用sql语句执行,二是可以用自己写个扩展方法来操作.虽然有不少人反对这方法.但我个人是倾向于自己写个扩展方法.这样,有2个好处.一是给开发人员使用简单.二是方便管理. 虽然也有网友提出用ObjectStateManager.ChangeObjectState 来实现批量删除,但我是没有找到相关的批量删除方法.而且这个也经常会出异常.
 
        6.使用已编译的查询,虽然到EF5.0, LINQ 查询是自动缓存的.但使用编译查询会比自动缓存的效率高.
 
            使用编译查询,请参照http://msdn.microsoft.com/zh-cn/library/bb896297.aspx.
 
        7.预生成视图,
 
          具体操作如下:
 
http://blogs.msdn.com/b/appfabriccat/archive/2010/08/06/isolating-performance-with-precompiled-pre-generated-views-in-the-entity-framework-4.aspx
 
        8.还有一点,就是对于复杂的查询,我们要随时监控生成的查询语句.
 
           毕竟EF生成的语句,往往比我们生成的语句更加复杂,这个时候我们就要考虑是否通过其他方式来提高性能.
 
         9.更多EF性能优化,请参考http://msdn.microsoft.com/zh-cn/library/cc853327.aspx
 

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统