![]()
在.NET圈子里混過幾年的都知道,Dapper是個讓人又愛又恨的存在。愛它的人夸它快、輕、不廢話;恨它的人每次遇到批量插入幾千條數據時,都想把鍵盤砸了。
一個意大利開發者最近放出的NuGet包,把這件事從"手寫SQL寫到手抽筋"變成了三行代碼解決。上線不到兩周,GitHub星標破了800。
批量操作:Dapper的阿喀琉斯之踵
Dapper的設計哲學很簡單:你給我SQL,我給你速度。單條查詢場景下,它確實把Entity Framework按在地上摩擦——內存占用只有后者的1/5,執行速度快3到10倍。
但批量操作一直是它的盲區。
原生Dapper沒有`BulkInsert`,沒有`BulkUpdate`,更沒有`BulkDelete`。開發者被迫回到石器時代:要么寫循環逐條執行(性能災難),要么自己拼接SQL字符串(維護噩夢),要么臨時引入SqlBulkCopy(破壞了Dapper的統一性)。
Stack Overflow上關于"Dapper bulk insert"的問題有超過1200個投票,最高贊答案是個2016年的 workaround——用`DataTable`配合`SqlBulkCopy`,代碼量接近50行。
這個痛點存在了至少8年。微軟官方文檔里,Dapper的批量操作章節至今寫著"Consider using SqlBulkCopy for large datasets",翻譯成人話就是:這事我們不管。
Pignone.Dapper.BulkExtensions:一個 NuGet 包的解法
意大利開發者Marco Pignone在3月底發布了`Pignone.Dapper.BulkExtensions`,版本號1.0.0。他的解決思路很直接:既然Dapper不肯做,那我在外面包一層。
安裝方式和其他NuGet包沒區別:
`dotnet add package Pignone.Dapper.BulkExtensions`
使用方式更接近Dapper的原生風格。假設你有個`Product`類,批量插入變成這樣:
`using (var connection = new SqlConnection(connectionString))`
` var items = new List`
` new Product { Name = "Product 1", Price = 10 },`
` new Product { Name = "Product 2", Price = 20 }`
` await connection.BulkInsertAsync(items);`
沒有`DataTable`,沒有列映射配置,沒有連接字符串的特殊處理。`BulkInsertAsync`內部自動處理了表名解析、列名匹配、批量大小控制這些臟活。
Marco Pignone在發布帖里寫了四個設計原則:輕量、高性能、易用、不造輪子。前兩條是向Dapper致敬,后兩條是針對現有方案的吐槽——有些批量擴展包為了"通用性",引入了復雜的Fluent API和配置系統,反而違背了Dapper的初衷。
性能數據與適用邊界
這個包目前只支持SQL Server,這是最大的限制。Marco在README里坦承:PostgreSQL和MySQL的適配"在路線圖里,但沒有時間表"。
對于SQL Server用戶,它底層用的是`SqlBulkCopy`,所以性能天花板和原生方案一致。Marco貼了一個非正式測試:插入10萬條記錄,逐條循環需要4分12秒,用這個包需要3.8秒——提升約66倍。
這個數字和SqlBulkCopy的理論性能吻合,說明包裝層沒有明顯損耗。
但有幾個場景它并不適用:
需要復雜轉換邏輯的數據遷移(還是用SSIS或專門工具更穩);
超大數據集(百萬級以上)的內存敏感場景——它目前是一次性加載整個列表;
非SQL Server數據庫——會拋`NotSupportedException`。
Marco在討論區回復用戶提問時說:「這個包的目標不是覆蓋所有場景,而是解決80%開發者遇到的80%問題。剩下的20%,你應該知道自己在做什么。」
社區反饋與后續走向
發布兩周內,這個包在NuGet上的下載量突破了3500次。GitHub倉庫收到了17個issue,其中12個是功能請求(MySQL支持、批量更新、部分列插入),5個是bug報告(已修復3個)。
一個有意思的細節:有用戶在issue里貼了自己的封裝版本,代碼結構和Marco的幾乎一致——說明這個需求確實普遍,只是之前沒人專門做成開源包。
Marco的更新節奏是每周一個小版本。1.1.0已經加入了`BulkUpdateAsync`,1.2.0計劃支持`BulkDeleteAsync`。他在最新回復里提到,正在評估Dapper的`ITypeHandler`機制,看能不能讓PostgreSQL支持不需要重寫核心邏輯。
這個包的MIT許可證也降低了采用門檻。有用戶在評論里說:「終于不用在每個項目里復制粘貼那套SqlBulkCopy樣板代碼了。」
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
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.