天天看點

提高Entity Framework性能的一些建議

LINQ to Entity是用于查詢和管理資料庫的極好的ORM。 它提供了很多東西,是以必須了解它的性能。LINQ在某一些地方有它自己的壞處。 在使用Entity Framework ORM設計和查詢資料庫時,我們應該記住一些提示和技巧。 

  • 避免将所有DB對象放入一個單一實體模型中

  實體模型指定了單個工作單元,而不是我們所有的資料庫。如果我們有很多資料庫對象沒有彼此連接配接,或者這些(日志表,批處理程序使用的對象等)根本不被使用。是以,這些對象正在消耗記憶體中的空間并導緻性能下降。是以嘗試制作相關資料庫對象的獨立實體模型。

  • 如果不需要,禁用實體的更改跟蹤

  每當您檢索資料僅用于閱讀目的時,不要進行修改,是以不需要對象跟蹤。 是以,通過使用MergeOption禁用對象跟蹤,如下所示:

1 NorthwindDataContext context = new NorthwindDataContext();
2 context.tblCities.MergeOption = MergeOption.NoTracking;       

  此選項允許我們關閉對象緩存和對象不必要的辨別管理。

  • 使用“預生成視圖”可以減少首次請求的響應時間

  當ObjectContext的對象在應用程式中第一次建立時,實體架構将建立一組通路資料庫所需的類。 這組類稱為視圖,如果您的資料模型很大,則建立視圖可能會延遲Web應用程式對頁面的第一個請求的響應。 我們可以通過使用T4模闆或EdmGen.exe指令行工具在編譯時建立視圖來減少此響應時間。

  • 如果不需要,避免提取所有字段

  避免從資料庫中擷取不需要的字段。 假設我有20個字段的Customer表,我隻對三個字段感興趣,即CustomerID,Name,Address,然後隻讀取這三個字段,而不是提取Customer表的所有字段。

  

1 // 不好的實踐
 2 var customer =
 3 (from cust 
 4 in dataContext.Customers
 5 select cust
 6 ).ToList();
 7 
 8 // 最佳實踐
 9 var customer =
10 (from cust 
11 in dataContext.Customers
12 select new {
13     customer. CustomerID,
14     customer.Name,
15     customer.Address
16  }). ToList ();       
  • 為資料操作選擇适當的集合

  在LINQ我們有var,IEnumerable,IQueryable,IList類型的集合用于資料操作。每種集合對查詢都有重要作用和性能影響,是以請小心使用這些集合進行資料操作。為了學習所有這些集合之間的差異,請參考文章:IEnumerable VS IQueryable , IEnumerable VS IList ,Var VS IEnumerable 。

  • 在需要的地方使用編譯查詢

  如果經常用于從資料庫擷取記錄,則對已編譯的查詢進行查詢。這個查詢在第一次很慢,但之後它顯著地提高了性能。 我們使用CompiledQuery類的編譯方法進行編譯查詢。假設您需要基于城市一次又一次地檢索客戶詳細資訊,然後将此查詢編譯為已編譯的查詢,如:

1 // 建立實體對象
 2 NorthwindEntities mobjentity = new NorthwindEntities();
 3  // 簡單查詢
 4 IQueryable lstCus = from customer in mobjentity.tblCustomers
 5 where customer.City == "Delhi"
 6 select customer;
 7 
 8 // 編譯查詢
 9 Func> compiledQuery
10 = CompiledQuery.Compile >
11 (
12     (ctx, city) => from customer in ctx.Customers
13                 where customer.City == city
14                 select customer
15 );       

在上面的查詢中,我們傳遞string類型的參數city來過濾記錄。

  • 僅檢索所需數量的記錄

  當我們将資料綁定到Grid或進行分頁時,僅檢索所需的記錄數以提高性能。 這可以通過使用Take,While和Skip方法來實作。如下所示的分頁:

1  // 建立實體對象
2 NorthwindEntities mobjentity = new NorthwindEntities();
3 int pageSize=10,startingPageIndex=2;
4 List lstCus = mobjentity.tblCustomers.Take(pageSize)
5                                      .Skip(startingPageIndex * pageSize)
6                                      .ToList();       
  • 避免使用Contains方法

  在LINQ中,我們使用Contains方法檢查資料是否存在。 但它在SQL中轉換為“WHERE IN”,導緻性能下降。

  • 避免在資料庫中使用視圖

  視圖降低了LINQ查詢性能。 它們性能較差,對LinQ性能影響很大。 是以避免在LINQ to Entities中使用視圖。

  • 調試和優化LINQ查詢

1 IQueryable lstCus = from customer in mobjentity.tblCustomers
2                     where customer.City == "Delhi"
3                     select customer;
4 lstCus.Dump();       

繼續閱讀