1.使用DbContext池
在Core Mvc中,如果使用 AddDbContextPool 方法,那么在控制器請求 DbContext 實例時,我們會首先檢查池中有無可用的實例。 請求處理完成后,實例的任何狀態都將被重置,並且實例本身會返回池中。 從概念上講,此方法類似於 ADO.NET 連接池的運行原理,並具有節約 DbContext 實例初始化成本的優勢。
eg:
services.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));
2.優先使用異步方法
EF Core 中提供了很多形如 xxxAsync 的異步方法,推薦使用這些方法提高吞吐量和性能,減少不必要的延時等待。
3.多活動結果集連接復用
多活動結果集 (MARS) 是一項允許對單個連接執行多個批處理的功能。 在以前的版本中,在單個連接上一次只能執行一個批處理。 使用 MARS 執行多個批處理並不意味着同時執行操作。 在連接字符串中添加:MultipleActiveResultSets=True 即可啟用 MARS 特性。
詳細見:https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets
4.批處理語句
EFCore中有一個重大改進,就是批處理,比如向數據庫中增加n條數據(n>3),會組合成一次請求訪問數據庫(而在以前的EF中,不是批處理,增加幾條,則會訪問幾次)。
注:操作數據條數 <=3 的時候,不會批處理,還是分多次請求,只有>3,才會批處理。
PS:可以手動設置批處理的條數MaxBatchSize,默認值很大。optionsBuilder.UseSqlServer("Server=localhost;Database=EFDB01;User ID=sa;Password=123456;", b => b.MaxBatchSize(10));
(1). 增加
1 //1.增加 (3條及以下不合並,3條以上合並) 2 for (int i = 0; i < 5; i++) 3 { 4 dbContext.Add(new T_UserInfor() { id = Guid.NewGuid().ToString("N"), userAge = i, addTime = DateTime.Now }); 5 } 6 int count = dbContext.SaveChanges();

(2). 修改
1 //2.修改(3條及以下不合並,3條以上合並) 2 var list = dbContext.T_UserInfor.Take(5).ToList(); 3 foreach (var item in list) 4 { 5 item.userSex = "男111"; 6 } 7 int count2 = dbContext.SaveChanges();

(3). 混合操作
1 //3.插入、更新、刪除的混合操作 (3條及以下不合並,3條以上合並) 2 var list3 = dbContext.T_UserInfor.Take(2).ToList(); 3 //增加 4 for (int i = 0; i < 2; i++) 5 { 6 dbContext.Add(new T_UserInfor() { id = Guid.NewGuid().ToString("N"), userAge = i, addTime = DateTime.Now }); 7 } 8 //更新 9 foreach (var item in list3) 10 { 11 item.userAge = 12; 12 } 13 //刪除 14 dbContext.Entry(list3.Take(1).FirstOrDefault()).State = EntityState.Deleted; 15 int count3 = dbContext.SaveChanges();

5.關閉狀態追蹤
跟蹤行為決定了 EF Core 是否將有關實體實例的快照信息保留在其更改跟蹤器中。 如果已跟蹤某個實體,則該實體中檢測到的任何更改都會在 SaveChanges() 期間永久保存到數據庫。當決定只查詢數據,不更改數據時,非跟蹤查詢十分有用,非跟蹤查詢的執行會更快,因為無需為查詢實體設置快照跟蹤信息。 如果不需要更新從數據庫中檢索到的實體,則應優先使用非跟蹤查詢。
(1).單體查詢關閉:AsNoTracking()
(2).整個上下文關閉:context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
6.關閉狀態同步
當從數據庫進行查詢數據時,上下文便捕獲了每個實體屬性的快照(數據庫值,原始值,當前值),當調用SaveChanges 時,在內部會自動調用 DetectChanges 方法,此方法將掃描上下文中所有實體,並比較當前屬性值和存儲在快照中的原始屬性值,如果被找到的屬性值發生了改變,此時EF將會與數據庫進行交互,進行數據更新。會導致自動調用 DetectChanges 方法: Find、Local、Remove、Add、Update、Attach、SaveChanges 和Entry 等。 但是,自動同步狀態會頻繁調用,可手動關閉以上方法的自動同步,當數據都修改好后,一次性手動同步。
關閉:context.ChangeTracker.AutoDetectChangesEnabled = false;
開啟:context.ChangeTracker.DetectChanges();
7.使用 EF.Functions.xxx 進行查詢
(1).使用 EF.Functions.Like進行模糊查詢要比 StartsWith、Contains 和 EndsWith 方法生成的SQL語句性能更優。
A. Contains語句,生成的sql為:
var data3 = dbContext.T_UserInfor.Where(u => u.userName.Contains("p")).ToList();
用的是charindex

B. EF.Functions.Like語句生成的sql為:
var data1 = dbContext.T_UserInfor.Where(u => EF.Functions.Like(u.userName, "%p%")).ToList(); //或者 var data2 = (from p in dbContext.T_UserInfor where EF.Functions.Like(p.userName, "%p%") select p).ToList();
用的是Like

PS:在傳統的.Net中,還有種用法 SqlMethods,詳見:https://www.cnblogs.com/yaopengfei/p/11805980.html
(2).還有EF.Functions.DateDiffDay (DateDiffHour、DateDiffMonth),求天、小時、月之間的數量
PS:在EF Core中StartsWith、Contains和EndsWith模糊查詢實際分別被解析成為Left、CharIndex和Right,而不是Like,而EF.Functions.Like會解析成Like語句。
詳見:https://www.cnblogs.com/tdfblog/p/entity-framework-core-like-query.html
8.DbFunctionAttribute 標量函數
EF Core 支持映射數據庫中定義的函數,可以在 LINQ 查詢中使用,該功能支持將數據庫標量函數映射到方法存根,使其可用於 LINQ 查詢並轉換為 SQL。 在 DbContext 上聲明靜態方法,並使用 DbFunctionAttribute 對其批注.
!
- 作 者 : Yaopengfei(姚鵬飛)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 本人才疏學淺,用郭德綱的話說“我是一個小學生”,如有錯誤,歡迎討論,請勿謾罵^_^。
- 聲 明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
