查缺補漏系統學習 EF Core 6 - 批量操作

推薦關注「碼俠江湖」星標,時刻不忘江湖事

這是 EF Core 系列的第七篇文章,上一篇文章講述了 EF Core 中的實體數據修改。

這篇文章講一講 EF Core 如何進行批量操作。

在眾多的 ORM 框架中,EF Core 的功能并不是最強大的那個,性能可能也不是最好的那個。但卻一直是最穩定、最安全,擴展能力最強、使用人數最多的那個。

雖然在性能方面,在 EF Core 6.0 中已經得到了非常大的提升。

但是在功能方面, EF Core 一直有一個不完善的地方,就是它不能很好的支持數據的批量操作,也就是批量刪除和批量更新。

所以這篇文章就先從比較常用的批量刪除和批量更新講起。

點擊上方或后方藍字,閱讀 EF Core 系列合集。

1a684269619a8fd731a086a39615db20.png

批量操作

在 EF Core 中批量更新和刪除數據,都需要先進行查詢,把數據加載到內存中,然后再對數據操作,最后再SaveChanges 保存到數據庫。

我們來看這個示例:

var?accounts?=?_context.Accounts.Where(account?=>?account.Age?>=?1);foreach?(var?a?in?accounts)
{a.Age?=?a.Age?+?1;
}_context.SaveChanges();

為了更新 Accounts 中實體的 Age 屬性,我們必須查詢出所有符合條件的實體集合,然后用遍歷的方式,在內存中去逐個修改實體的 Age 屬性。

最后,通過 SaveChanges 方法保存修改。

運行程序,結果如下圖所示:

cce63becd4a126e8311b1d17e9203667.png

通過控制臺日志可以發現,前后總共執行了 3 條 SQL 語句,1 條 Selet 語句和 2 條 Uptete 語句。

第一條 Selet 語句,是為了查詢出所有符合條件的數據,由于數據庫中只有 2 條數據,所以后面 2 條 Uptete 語句,是針對這 2 條數據的更新操作。

如果我們把更新操作換成刪除操作,EF Core 也會如此去做。

大家可以想象一下,如果批量更新或者刪除的數據量比較大,那么這樣的操作,性能無疑是非常底下的。

因此,我們需要一種在 EF Core 中,只使用一條 SQL 語句,就可以批量刪除或更新數據的方法。

由于這個功能確實比較常用,很多其它第三方的 ORM 框架,幾乎也都支持這個操作。

但為什么作為 ORM 框架大佬的 EF Core,卻不提供這個功能呢?

簡單來說,EF Core 的開發團隊認為,這樣做會導致 EF Core 的對象狀態跟蹤混亂。

比如對于同一個上下文類,如果用批量刪除的方法刪除了數據,那么在被刪除之前,查詢出來的數據狀態就混亂了。

畢竟,EF Core 是一個成熟且安全性高的 ORM 框架,必然會考慮潛在風險的存在。

如果想要完美實現,可能需要重構 EF Core 的代碼,工作量方面會比較大。

但是,我們作為開發者,完全可以根據場景需求,來規避這些問題的存在。

比如在一個 Web 應用中,刪除操作通常都是在一個 HTTP 請求中完成的,不同的 HTTP 請求上下文是不同的,所以基本不會涉及到 EF Core 開發團隊擔心的問題。

即便在某些特殊場景下,涉及到在同一個上下文里,數據刪除之前就把數據查詢出來的場景,那也完全可以通過在刪除之后,再重新查詢一次的方式,來規避這個問題。

未來 EF Core 會不會添加這個功能,我們不得而知,但我們也有自己的解決方法。

第一個解決方法,就是執行原生 SQL 語句,不過它的缺點我們在前面的文章中已經提過,就不再多說。

第二個解決方法,是使用第三方的 ORM 框架,比如 FreeSQL、SugarSQL,它們都提供了批量更新和批量刪除的功能,使用起來也非常簡單。

不過,這種方法的缺點就是必須在項目替換掉 EF Core ,使用第三方的 ORM 框架。

目前 EF Core 是 .NET 中,使用率最高的 ORM 框架,主打安全性與穩定性,而且 6.0 版本性能也得到了大量的改善,所以不建議輕易更換。

第三個解決方法,就是使用 EF Core 的擴展插件,由于 EF Core 在全球范圍有著最多的用戶基數,所以也形成了一個強大的生態環境,擁有很多的第三方擴展。

這同樣也是第三方 ORM 框架,所無法比擬的地方。

我們可以在 EF Core 的官方文檔,查閱到被官方收集的第三方擴展插件和工具。

這里面支持批量操作的擴展插件有兩個:「EFCore.BulkExtensions」「Entity Framework Plus」

它們都支持最新的 EF Core,更新也比較穩定。

不同的是,E「FCore.BulkExtensions」 功能專一,僅擴展了批量操作方面的功能,同時也支持 「SqlBulkCopy」,也就是大數據量的批操作。

由于 「SqlBulkCopy」 只支持 SQLServer 和 SQLite ,所以 「EFCore.BulkExtensions」 只支持 SQLServer 和 SQLite。

「EF Plus」 功能更加強大,擴展了更多的查詢功能,它分為免費版和收費版,基礎的批量操作免費版就可以支持,高級批量操作以及 SqlBulkCopy 則只有收費版支持。

如果使用的是 MySQL,或者不需要 SqlBulkCopy,那么 「EF Plus 免費版」是首選,因為它支持更多的數據庫,擴展了更豐富的查詢功能。

安裝好 EF Plus,這里我將剛才批量更新的操作,改為 EF Plus 來實現:

<PackageReference?Include="Z.EntityFramework.Plus.EFCore"?Version="6.13.19"?/>
_context.Accounts.Where(account?=>?account.Age?>=?1).Update(account?=>?new?Account?{Age?=?account.Age?+?1},update?=>?update.Executing?=?command?=>?Console.WriteLine(command.CommandText));

Update 就是 EF Plus 擴展的方法,它的第一個參數是要更新的數據,第二個參數是一個執行攔截器委托,這里用來打印準備執行的 SQL 語句。

現在運行程序,可以在控制臺中看到:

679cd77da4480bc0290256ab0efcf701.png

執行的是 1 條 UPDATE 語句,這條 SQL 語句會更新所有 Accounts 中符合條件的 Age 字段。

除了批量更新,批量刪除也同樣簡單。

更多的示例,大家可以看 EF Plus 的官網文檔。

更多精彩內容,請關注我▼▼

3eeaf41a420eaa9b9ee0b76698ada1d6.gif

如果喜歡我的文章,那么

在看和轉發是對我最大的支持!

(戳下面藍字閱讀)

e7167ee188e765616a3fa721635d064a.png

推薦關注微信公眾號:碼俠江湖

? ? ? ? ? ? ? ? ? ? ? ??08863a258d6cbe8b39ed5ec759bb23d0.png覺得不錯,點個在看再走喲

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

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

相關文章

半小時一篇文過完C語言基礎知識點

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本文定位讀者為小白讀者&#xff0c;將使用最快的方法過完C語言基礎知識…

php變量的判空和類型判斷

&#xff08;1&#xff09;var_dump(); 判斷一個變量是否已經聲明并且賦值&#xff0c;并且打印類型和值 <?php $a; var_dump($a);//輸出null<?php var_dump($a);//輸出null<?php$a 10; var_dump($a);//輸出 int 10&#xff08;2&#xff09;isset() 判斷一個變量…

【Envi風暴】Envi插件大全:多波段拆分工具的巧妙使用

很多場合下需要做波段合成,比如波段432合成賦予紅綠藍,構造標準假彩色等等。合成后的文件通常包含多個單波段文件,在Envi中使用layer stacking工具將多個單波段數據合成為一個文件,如下所示: 那么問題來了,合成后的數據該怎樣拆開為原來的單波段呢?今天我們就來學習一種…

php表格怎么合并單元格格式化,table標簽的結構與合并單元格的實現方法

1.示例代碼&#xff1a;復制代碼 代碼如下:#1234一個完整的例子&#xff1a;復制代碼 代碼如下:#FirstnameLastnamePhoneQQ1qianshou111111111111111111112qianshou111111111111111111113qianshou111111111111111111114qianshou111111111111111111112.合并上下的單元格(rowspan…

Android之GridLayoutManager.setSpanSizeLookup問題

1 問題 利用BaseMultiItemQuickAdapter,用recycleView加載多布局,需要實現有些view顯示一行,有些一行顯示多個圖片。 在BaseMultiItemQuickAdapter適配器里面根據類型加載不同布局。 public ImageMultiItemAdapter(List<MultiItemEntity> data) {super(data);addIte…

《看聊天記錄都學不會C語言?太菜了吧》(9)老公餅真的有老公送?

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

@Springboot搭建項目controller層接收json格式的對象失敗

今天在使用swagger2測試的時候出錯 1、requestBody注解常用來處理content-type不是默認的application/x-www-form-urlcoded編碼的內容&#xff0c;比如說&#xff1a;application/json或者是application/xml等。一般情況下來說常用其來處理application/json類型。 2、 通過req…

『技術群里聊些啥』HttpClient 如何判斷是同一終結點

前言官方文檔對 HttpClientHandler.MaxConnectionsPerServer 屬性有如下說明&#xff1a;獲取或設置使用 HttpClient 對象發出請求時允許的最大并發連接數&#xff08;每個服務器終結點&#xff09;。請注意&#xff0c;該限制針對每個服務器終結點&#xff0c;例如&#xff0c…

【Envi風暴】Envi 5.3 SP1經典安裝手把手圖文教程(含補丁文件)

Envi 5.3具有傳感器和數據支持、圖像處理和顯示、用戶界面、二次開發等新功能,本文講解Envi 5.3 SP1完全安裝教程。 下載后的軟件包目錄如下所示: 目錄 一、Envi 5.3 SP1安裝 二、Envi 5.3 SP1下載地址 一、Envi 5.3 SP1安裝 點擊IDL_ENVI5.3 SP1win64.exe,開始安裝,…

apache php url重寫語法,apache url重寫實現偽靜態

前段時間項目為了配合seo的工作&#xff0c;把現有的php網站改成靜態頁面&#xff0c;剛拿到需求時候第一感覺就是用靜態頁面啊&#xff0c;可是看了一會以后發現頁面有點多4、50個&#xff0c;沒辦法就用比較簡單的url重寫(apache的)吧&#xff0c;去掉這個前面的#,啟用它Load…

Android之用java的socket寫服務器提示java.net.BindException: Address already in use

1 問題 在Android activity里面Java socket服務器,然后關閉activity再打開activity開啟服務的時候提示錯誤如下 java.net.BindException: Address already in use 很明顯這個,IP和端口的的socket已經使用了,我們只需要在關閉activity的時候關閉serverSocket就行了。 2 解…

《看聊天記錄都學不會C語言?太菜了吧》(10)程序媛聰明絕頂了

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

List 集合轉換為String

開發中會用到把 List<string> 的內容拼接成以逗號分隔的字符串的形式,現總結如下&#xff1a; 方法一: public String listToString(List list, char separator) { StringBuilder sb new StringBuilder(); for (int i 0; i < list.size(); i) { …

[leetcode]Pascal#39;s Triangle II

問題敘述性說明&#xff1a; Given an index k, return the kth row of the Pascals triangle. For example, given k 3, Return [1,3,3,1]. Note: Could you optimize your algorithm to use only O(k) extra space? 思路&#xff1a; the mth element of the nth row of th…

遙感方法研究張掖市1999-2010年土地利用變化

【方法思路】:本文選取張掖地區兩期影像(Landsat 1999-07-07,2010-09-07),用監督分類方法獲取各期土地利用類型,與已有的土地利用現狀矢量圖(landuse2000)相疊加,通過對比分析,進而得出張掖市1999-2010年間土地利用變化情況。 一、實驗數據 采用Landsat Tm影像,原始…

【MongoDB】遞歸獲取字段更新表達式,更新復雜數據類型對象

在實際更新Mongo對象時發現&#xff0c;原有的更新代碼無法更新復雜的數據類型對象。恰好看到張占嶺老師有對該方法做相關的改進&#xff0c;因此全抄了下來。 總的核心思想就是運用反射與遞歸&#xff0c;對對象屬性一層一層挖掘下去&#xff0c;循環創建父類及之類的更新表達…

java openxml 操作 word,openxml word轉成xml

word2007無法打開Office Open XML 文檔由于種種原因&#xff0c;如程序安裝錯誤、注冊表被修改&#xff0c;或系統被病毒侵害等。有時候會造成WORD 2007無法打開.DOC文檔的問題&#xff0c;常規的處理辦法(右鍵選擇“打開方式”)無效。可以試試如下的方法 &#xff1a;1.打開注…

聊一聊CLR源碼中的 #define 是怎么玩的

一&#xff1a;背景 如果大家看過 CLR 源碼&#xff0c;會發現里面有很多 #define 宏定義,比如說 fusionhelpers.hpp 頭文件里。如果你不熟悉 C &#xff0c;看到這些 #define 應該會很暈的&#xff0c;這篇我們就來簡單聊聊 define 的玩法&#xff0c;其實說白了很簡單, #defi…

《看聊天記錄都學不會C語言?太菜了吧》(11)2分鐘領悟數組

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

Android之android8.1打開熱點提示UID 10140 does not have Location permission和Location mode is enabled.

1 問題 在三星安卓8.1版本手機上,打開熱點 WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {@TargetApi(Build.VERSION_CODES.O…