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

简介: 转自:http://www.cnblogs.com/jake1/archive/2013/04/25/3043664.html     我发现现在有不少博友,都反对使用EF框架,说它性能低.其实只要你用的好,性能不是问题,经过测试,它也会接近ado.

转自:http://www.cnblogs.com/jake1/archive/2013/04/25/3043664.html  

  我发现现在有不少博友,都反对使用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

目录
相关文章
|
JSON 安全 Dubbo
实践指南:WebSocket 鉴权的最佳实践
WebSocket 作为实时通信的利器,越来越受到开发者的青睐。然而,为了确保通信的安全性和合法性,鉴权成为不可或缺的一环。本文将深入探讨 WebSocket 的鉴权机制,为你呈现一揽子的解决方案,确保你的 WebSocket 通信得心应手。
实践指南:WebSocket 鉴权的最佳实践
|
存储 缓存 前端开发
关于JWT Token 自动续期的解决方案
关于JWT Token 自动续期的解决方案
1932 1
|
JSON 中间件 Go
给Go的Gin web框架增加 WebSocket 功能,让WebSocket 更好用
给Go的Gin web框架增加 WebSocket 功能,让WebSocket 更好用
|
存储 BI 数据库
Entgo 实现 软删除(Soft Delete)
软删除(Soft Delete)这种删除方式并不是真正地从数据库中把记录删除,而是通过特定的标记方式在查询的时候将此记录过滤掉。虽然数据在界面上已经看不见,但是数据库还是存在的。
1938 1
|
存储 缓存 NoSQL
Redis之布隆过滤器(Bloom Filter)解读
Redis之布隆过滤器(Bloom Filter)解读
|
存储 缓存 NoSQL
亿级数据判断 bitmap-布隆过滤器
亿级数据判断 bitmap-布隆过滤器
323 0
亿级数据判断 bitmap-布隆过滤器
|
存储 缓存 前端开发
java后端实现token自动续期,这方案有点优雅
在前后端分离的开发模式下,前端用户登录成功后后端服务会给用户颁发一个token。前端(如vue)在接收到 token后会将token存储到LocalStorage中。
2988 0
|
6天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。