EF Core 異步方法

文章目錄

  • 前言
  • 一、為什么使用異步方法
  • 二、核心異步方法
    • 1)查詢數據
    • 2)保存數據
    • 3)事務處理
  • 三、異步查詢最佳實踐
    • 1)始終使用 await
    • 2)組合異步操作
    • 3)并行查詢(謹慎使用)
  • 四、異常處理
  • 五、性能注意事項
    • 1)DbContext 生命周期
    • 2)取消操作支持
    • 3)禁用跟蹤(只讀場景)
  • 六、常見錯誤
    • 1)混合同步/異步調用
    • 2)未正確處理上下文
  • 七、高級模式
    • 1)批量操作
    • 2)原始 SQL 查詢
  • 總結
    • EF Core 的異步方法通過以下方式提升性能:
    • 關鍵要點:


前言

在 Entity Framework Core 中,異步方法是優化數據庫操作性能、避免阻塞線程的關鍵工具,特別適用于 Web 應用、API 或其他高并發場景。


一、為什么使用異步方法

  1. 避免線程阻塞:異步操作釋放當前線程(如 ASP.NET 的請求線程),提高吞吐量。
  2. 提升響應性:在 UI 應用(如 WPF、MAUI)中防止界面卡死。
  3. 高效利用資源:適合長時間運行的數據庫操作(如復雜查詢、批量寫入)。

二、核心異步方法

EF Core 為常見操作提供了異步版本,需結合 async/await 使用:

1)查詢數據

  1. ToListAsync():異步返回列表
  2. FirstOrDefaultAsync():異步獲取首個匹配項
  3. SingleOrDefaultAsync():異步獲取唯一匹配項
  4. CountAsync():異步統計數量
  5. AnyAsync():異步檢查是否存在
public async Task<List<Person>> GetActivePersonsAsync()
{using var context = new MyDbContext();return await context.Persons.Where(u => u.Name=="Tom").ToListAsync(); // 異步執行查詢
}

2)保存數據

  1. SaveChangesAsync():異步提交更改
  2. AddAsync():異步添加單個實體(通常用于值生成策略)
public async Task CreatePersonsAsync(Person person)
{using var context = new MyDbContext();await context.Persons.AddAsync(person); // 異步添加await context.SaveChangesAsync();    // 異步提交
}

3)事務處理

public async Task TransferMoneyAsync(int fromId, int toId, decimal amount)
{using var context = new MyDbContext();using var transaction = await context.Database.BeginTransactionAsync();try{var fromAccount = await context.Accounts.FindAsync(fromId);var toAccount = await context.Accounts.FindAsync(toId);fromAccount.Balance -= amount;toAccount.Balance += amount;await context.SaveChangesAsync();await transaction.CommitAsync();}catch{await transaction.RollbackAsync();throw;}
}

三、異步查詢最佳實踐

1)始終使用 await

// ? 正確
var persons = await context.Persons.ToListAsync();// ? 錯誤(立即阻塞線程)
var persons = context.Persons.ToListAsync().Result;

2)組合異步操作

public async Task<Person> GetPersonWithOrdersAsync(int personId)
{return await context.Persons.Include(u => u.Orders).FirstOrDefaultAsync(u => u.Id == personId);
}

3)并行查詢(謹慎使用)

var task1 = context.Persons.CountAsync();
var task2 = context.Orders.CountAsync();await Task.WhenAll(task1, task2);var totalPersons = task1.Result;
var totalOrders = task2.Result;

四、異常處理

try
{await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException ex)
{// 處理并發沖突
}
catch (DbUpdateException ex)
{// 處理更新錯誤
}

五、性能注意事項

1)DbContext 生命周期

  1. 確保在 using 塊或依賴注入范圍內使用,避免內存泄漏。

2)取消操作支持

  1. 多數異步方法接受 CancellationToken

    var cts = new CancellationTokenSource();
    var users = await context.Persons.ToListAsync(cts.Token);
    

3)禁用跟蹤(只讀場景)

var persons = await context.Persons.AsNoTracking().ToListAsync();

六、常見錯誤

1)混合同步/異步調用

// ? 危險!可能導致死鎖
public Person GetPerson(int id)
{return context.Persons.FirstOrDefaultAsync(u => u.Id == id).Result;
}

錯誤修正(修正為異步方法)

  1. 始終優先使用 async/await,避免 .Result 或 .Wait()
public async Task<Person> GetPersonAsync(int id)
{return await context.Persons.FirstOrDefaultAsync(u => u.Id == id);
}

2)未正確處理上下文

// ? 上下文可能被提前釋放
public async Task<List<Person>> GetPersonsAsync()
{using var context = new MyDbContext();return await context.Persons.ToListAsync(); 
} // 上下文在此處釋放,返回的實體可能無法延遲加載

錯誤修正(將原始代碼改為安全模式)

  1. 優先使用 DTO 或投影
    避免直接返回實體,尤其是在 Web API 中。
  2. 明確加載關聯數據
    使用 IncludeSelect 確保所有需要的數據已加載。
  3. 默認禁用跟蹤
    在只讀場景中,始終使用 AsNoTracking 提升性能。
  4. 嚴格管理 DbContext 生命周期
    Web 應用中,通過依賴注入(Scoped 生命周期)管理 DbContext
    桌面應用中,確保 DbContext 生命周期與 UI 操作同步。
// ? 安全:返回 DTO,無需延遲加載
public async Task<List<PersonDto>> GetPersonsAsync()
{using var context = new MyDbContext();return await context.Persons.Select(p => new PersonDto {Id = p.Id,Name = p.Name}).AsNoTracking().ToListAsync(); 
}

七、高級模式

1)批量操作

await context.BulkInsertAsync(entities); // 使用 EF Plus 等擴展庫

2)原始 SQL 查詢

var persons = await context.Persons.FromSqlInterpolated("SELECT * FROM T_Persons WHERE Age > {0}", 18).ToListAsync();

總結

EF Core 的異步方法通過以下方式提升性能:

  1. 減少線程阻塞
  2. 提高服務器吞吐量
  3. 優化資源利用率

關鍵要點:

  1. 始終 await 異步方法
  2. 正確處理上下文生命周期
  3. 結合 CancellationToken 實現可控取消
  4. 避免混合同步/異步代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74790.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74790.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74790.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

裝飾器模式介紹和典型實現

裝飾器模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許你通過將對象放入包含行為的特殊封裝對象中來為原對象添加新的功能。裝飾器模式的主要優點是可以在運行時動態地添加功能&#xff0c;而不需要修改原對象的代碼。這使得代碼更加靈活…

【 <二> 丹方改良:Spring 時代的 JavaWeb】之 Spring Boot 中的日志管理:Logback 的集成

<前文回顧> 點擊此處查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、開篇整…

神經網絡知識點整理

目錄 ?一、深度學習基礎與流程 二、神經網絡基礎組件 三、卷積神經網絡&#xff08;CNN&#xff09;?編輯 四、循環神經網絡&#xff08;RNN&#xff09;與LSTM 五、優化技巧與調參 六、應用場景與前沿?編輯 七、總結與展望?編輯 一、深度學習基礎與流程 機器學習流…

【sql優化】where 1=1

文章目錄 where 11問題描述錯誤實現正確實現性能對比測試 where 11 問題描述 在動態 SQL 拼接場景中&#xff0c;開發者常使用 WHERE 11 簡化條件拼接邏輯&#xff08;避免處理首個條件的 AND&#xff09;。理論上&#xff0c;數據庫優化器會忽略 11&#xff0c;但字符串拼接…

車載以太網網絡測試 -24【SOME/IP概述】

目錄 1 摘要2 車載SOME/IP 概述2.1發展背景以及應用2.1.1車載 SOME/IP 背景2.1.2 車載 SOME/IP 應用場景 2.3 什么是SOME/IP2.3.1 SOME/IP定義2.3.2 SOME/IP在協議棧中的位置 3 SOA是什么4 SOME/IP主要功能5 SOME/IP標準 1 摘要 本文主要介紹SOME/IP的背景以及在車載行業的發展…

vue3中,route4,獲取當前頁面路由的問題

首先應用場景如下&#xff1a; 在main.js里面&#xff0c;引入的是路由的配置文件&#xff0c;如下&#xff1a; import {router} from /router; app.use(router); 路由配置文件router.js如下&#xff1a; import { createRouter, createWebHistory } from vue-router; imp…

ip改變導致的數據庫連接不上

前言 需要用到路由器&#xff0c;所以先把家里的路由器給拆了先用著。新的路由器到了之后&#xff0c;更換上新的路由器之后&#xff0c;調用到服務會有報錯&#xff0c;記錄一下更換路由器之后ip重新分配服務可能會報的錯. 進一步可以看到有關網路在服務當中的影響。 正文 …

Chrome 開發環境快速屏蔽 CORS 跨域限制!

Chrome 開發環境快速屏蔽 CORS 跨域限制【詳細教程】 ? 為什么需要臨時屏蔽 CORS&#xff1f; 在前后端開發過程中&#xff0c;我們經常會遇到 跨域請求被瀏覽器攔截 的問題。例如&#xff0c;你在 http://localhost:3000 調用 https://api.example.com 時&#xff0c;可能會…

【力扣hot100題】(009)和為K的子數組

還是太菜了&#xff08;我&#xff09;&#xff0c;寫了半天滑動窗口&#xff0c;然后看了答案又寫了半天時間超限…… 總之就是記錄每前n個子串的和&#xff0c;然后使用hash存儲和為某個值出現的次數&#xff0c;每次求得新和就看看是否存在前面新和-k的字符&#xff0c;有的…

使用 rsync 進行服務器文件同步與優化

使用 Rsync 工具在兩臺 Linux 服務器之間同步文件 Rsync 是一種高效的文件同步工具&#xff0c;它可以在本地或遠程服務器之間同步文件和目錄。Rsync 通過僅傳輸文件的變化部分來減少數據傳輸量&#xff0c;因此特別適合用于定期備份或同步大量數據。本文將詳細介紹如何將 A 服…

卷積神經網絡 - 微步卷積、空洞卷積

一、微步卷積 微步卷積&#xff08;Fractionally Strided Convolution&#xff09;&#xff0c;通常也稱為轉置卷積&#xff08;Transposed Convolution&#xff09;或反卷積&#xff08;Deconvolution&#xff09;&#xff0c;是深度學習&#xff08;尤其是卷積神經網絡&…

詳解java體系實用知識總結

0.java技術能力框架 基礎模塊應用模塊綜合模塊技術崗位與面試流程常用工具集系統架構設計計算機基礎常用框架微服務架構jvm原理緩存容器化多線程隊列云計算&#xff08;阿里云/aws&#xff09;設計模式數據庫數據結構與算法 1.常用設計模式與應用場景 工廠模式&#xff1a;s…

設計模式之創建型5種

設計模式 為什么設計模式是23種創建型 對象創建為什么設計模式是23種 設計模式之所以被歸納為23種,而非其他數量,源于GoF(Gang of Four)在1994年的系統性總結和分類。這一數量的確定并非偶然,而是基于以下核心原因: 他們遵循“大三律”(Rule of Three),即只有經過三個…

Oracle 23ai Vector Search 系列之2 ONNX(Open Neural Network Exchange)

文章目錄 Oracle 23ai Vector Search 系列之2 ONNX(Open Neural Network Exchange)ONNX基本概念ONNX(Open Neural Network Exchange)ONNX Runtime ONNX Runtime 在Oracle數據庫中的集成參考 Oracle 23ai Vector Search 系列之2 ONNX(Open Neural Network Exchange) 我們在看【…

統一語言學習范式

摘要 現有的預訓練模型通常針對特定類別的問題。迄今為止&#xff0c;關于何種架構和預訓練設置應為最佳似乎仍未達成共識。本文提出了一個統一的框架&#xff0c;用于預訓練在多種數據集和設置中普遍有效的模型。我們首先將架構原型與預訓練目標這兩個常被混為一談的概念進行…

Flutter項目升級到指定版本的詳細步驟指南

一、升級前的準備工作 備份項目 使用Git提交當前所有修改&#xff1a;git commit -am "Pre-upgrade backup"或直接復制項目文件夾 查看當前環境信息 flutter --version flutter doctor二、升級Flutter SDK到指定版本 方法1&#xff1a;通過版本管理工具升級&#x…

22、web前端開發之html5(三)

六. 離線存儲與緩存 在網絡環境不穩定或需要優化資源加載速度的場景下&#xff0c;離線存儲與緩存技術顯得尤為重要。HTML5引入了多種離線存儲和緩存機制&#xff0c;幫助開發者提升用戶體驗。本節將詳細介紹Application Cache、localStorage、sessionStorage以及IndexedDB等技…

用HTML和CSS生成炫光動畫卡片

這個效果結合了漸變、旋轉和懸浮效果的炫酷動畫示例&#xff0c;使用HTML和CSS實現。 一、效果 二、實現 代碼如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&quo…

【嵌入式學習2】數組

目錄 ## 數組概念 ## 數組使用 ## 數組初始化 ## 數組名 ## 數組長度 ## 數組相關題目 1、找最大值 2、逆置 ## 數組和指針 指針加整數的含義 ## 指針數組 ## 數組名做函數參數 ## 函數參數傳遞數組 1、在函數內部 2. 在函數外部 ## 多維數組 使用下標訪問 #…

C++中的判斷與循環

一.if判斷語句 1.程序中的判斷&#xff1a; if (要執行的判斷&#xff0c;最后的返回值要是bool型的數據) {如果為真&#xff0c;要執行的代碼段; } #include"iostream" using namespace std;int main() {int ans;cin >> ans;if (ans > 1000) {cout <…