![]()
如果你用Dapper寫(xiě)過(guò)批量插入,大概率踩過(guò)這個(gè)坑:10萬(wàn)條數(shù)據(jù),循環(huán)ExecuteAsync要跑5分鐘,CPU風(fēng)扇轉(zhuǎn)得像直升機(jī)。
這不是Dapper的錯(cuò)。它的設(shè)計(jì)哲學(xué)就是"輕量、裸奔、你自己搞定",批量操作從來(lái)不在核心射程內(nèi)。但業(yè)務(wù)不等人,財(cái)務(wù)月底導(dǎo)數(shù)據(jù)、日志批量歸檔、遷移千萬(wàn)級(jí)歷史訂單——這些場(chǎng)景你躲不掉。
一個(gè)意大利開(kāi)發(fā)者Pignone最近扔了個(gè)NuGet包進(jìn)池子,名字直白得像個(gè)工具箱:Pignone.Dapper.BulkExtensions。兩周下載量破1.2萬(wàn),GitHub星標(biāo)還沒(méi)漲起來(lái),但.NET社群的討論帖已經(jīng)炸出一堆"早該如此"的抱怨。
批量操作的臟活,Dapper從來(lái)不接
Dapper的定位很清晰:把你寫(xiě)的SQL塞進(jìn)去,最快最省地拿回結(jié)果。它不做ORM的臟活累活,也不碰批量操作這種需要深度綁定數(shù)據(jù)庫(kù)特性的功能。
于是開(kāi)發(fā)者被迫自己造輪子。常見(jiàn)套路有幾種:手拼SQL用VALUES批量插入、開(kāi)事務(wù)分段提交、或者干脆換EF Core/ SqlBulkCopy。每種都有代價(jià)——手拼SQL維護(hù) nightmare,SqlBulkCopy要引額外依賴,EF Core又太重。
Pignone在文檔里寫(xiě)得很實(shí)在:「我受夠了每個(gè)項(xiàng)目都復(fù)制粘貼同一套批量操作代碼。」這個(gè)包的誕生動(dòng)機(jī),和大多數(shù)好的工具庫(kù)一樣——先解決自己的癢點(diǎn),再扔出來(lái)看能不能撓到別人。
核心賣點(diǎn)四個(gè)詞:輕量、高性能、易用、不整幺蛾子。安裝命令一行:
dotnet add package Pignone.Dapper.BulkExtensions
目前版本0.9.1,依賴只有Dapper本身和Microsoft.Data.SqlClient,沒(méi)塞任何花里胡哨的東西。
代碼能省多少?看組對(duì)比
傳統(tǒng)Dapper批量插入,你可能寫(xiě)成這樣:
開(kāi)事務(wù)、循環(huán)Execute、手動(dòng)分批、異常回滾——50行起步,還要調(diào)參數(shù)防內(nèi)存爆炸。Pignone的版本:
await connection.BulkInsertAsync(items);
就這一行。10萬(wàn)條數(shù)據(jù),內(nèi)部自動(dòng)走SqlBulkCopy管道,實(shí)測(cè)從5分鐘壓到8秒。當(dāng)然,具體數(shù)字看機(jī)器和網(wǎng)絡(luò),但量級(jí)差距是真實(shí)的。
接口設(shè)計(jì)延續(xù)了Dapper的直覺(jué):擴(kuò)展方法掛在IDbConnection上,傳泛型集合就行。支持異步、支持事務(wù)嵌套、遇到重復(fù)鍵可以選跳過(guò)或覆蓋——這些選項(xiàng)都藏在可選參數(shù)里,不打擾簡(jiǎn)單場(chǎng)景。
有個(gè)細(xì)節(jié)挺有意思:作者特意避開(kāi)了"全自動(dòng)映射"的誘惑。實(shí)體屬性和數(shù)據(jù)庫(kù)列的對(duì)應(yīng),還是要你顯式標(biāo)[Column]特性,或者用手動(dòng)映射表。這很Dapper——給你方便,但不替你拍腦袋。
誰(shuí)該用,誰(shuí)再等等
這個(gè)包的舒適區(qū)很明確:已經(jīng)在用Dapper、不想換技術(shù)棧、偶爾有批量操作需求的中型項(xiàng)目。如果你每天要導(dǎo)上億條數(shù)據(jù),可能還是得原生SqlBulkCopy或者專門(mén)的數(shù)據(jù)管道工具。
目前支持的操作類型有限:BulkInsertAsync、BulkUpdateAsync、BulkDeleteAsync,BulkMerge還在Roadmap上。數(shù)據(jù)庫(kù)方面只測(cè)了SQL Server,PostgreSQL和MySQL的適配器社區(qū)有人在提PR,但還沒(méi)合并。
作者放話要"持續(xù)演進(jìn),覆蓋更多.NET生態(tài)的批量場(chǎng)景"。這話聽(tīng)聽(tīng)就行,關(guān)鍵看迭代速度。0.9.1是3月底發(fā)的,GitHub上Issue響應(yīng)倒是挺快,有個(gè)用戶反饋"大數(shù)據(jù)量時(shí)內(nèi)存占用高",三天后作者就扔了個(gè)流式處理的實(shí)驗(yàn)分支。
一個(gè)值得玩味的點(diǎn):這個(gè)包的名字叫Pignone.Dapper.BulkExtensions,前綴是作者ID。在NuGet生態(tài)里,這種個(gè)人品牌命名通常意味著"我維護(hù),我負(fù)責(zé),也可能哪天棄坑"。但目前看commit記錄,作者至少給自己留了長(zhǎng)期維護(hù)的口子——CI/CD配了GitHub Actions,測(cè)試覆蓋率卡著80%的線。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.