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


       我發現現在有不少博友,都反對使用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM