Skip to content
Go back

用C#和EF Core实现高性能SQL批量插入全攻略

Published:  at  10:24 PM

用C#和EF Core实现高性能SQL批量插入全攻略 🚀

引言:大数据量插入的烦恼,开发者的痛点

在大型业务系统、数据分析平台或用户量激增时,.NET开发者常常面临一个老生常谈却又避无可避的问题:如何高效地把海量数据灌入数据库?
如果还在一条一条插,等得人都要怀疑人生了。别急!今天我们就用实际案例,带你揭秘C#和EF Core在大数据量插入下的性能优化“黑科技”,让你的Insert速度飙升14倍,节省94%的时间!


核心观点与结构梳理

本篇文章针对.NET开发者和对高性能数据库操作感兴趣的软件工程师,系统梳理了C#与EF Core批量插入的几种主流实现方法,并对每种方法进行了性能实测与对比:

每一部分均配有简单易懂的代码示例、详细的性能对比表和实战场景建议,让你轻松选出最适合自己项目的方案。


一、EF Core传统写法:一条一条加,慢到怀疑人生 🐢

很多朋友用EF Core时都是这样写的:

using var context = new ApplicationDbContext();
foreach (var user in GetUsers())
{
    context.Users.Add(user);
    await context.SaveChangesAsync();
}

性能实测:

结论:
这种写法是典型的“怎么别写怎么来”,每加一条都要往数据库跑一趟,效率感人。


二、Dapper简单插入:轻量高效

Dapper以轻便著称,插入时可以直接展开对象集合:

using var connection = new SqlConnection(connectionString);
connection.Open();
const string sql = @"
    INSERT INTO Users (Email, FirstName, LastName, PhoneNumber)
    VALUES (@Email, @FirstName, @LastName, @PhoneNumber);";
await connection.ExecuteAsync(sql, GetUsers());

性能实测:

小结:
比逐条Save快多了,但面对百万级数据仍然吃力。


三、EF Core批量AddRange:高效但保持易用性

改进版写法,一次性AddRange然后SaveChangesAsync:

using var context = new ApplicationDbContext();
context.Users.AddRange(GetUsers());
await context.SaveChangesAsync();

性能实测:

提示:比Dapper快了五倍,代码风格也更贴近Entity Framework的习惯。


四、EF Core Bulk Extensions库:速度更上一层楼 🔥

Bulk Extensions是社区极力推荐的高性能批量操作库,支持批量插入、更新、删除和合并等操作。

using var context = new ApplicationDbContext();
await context.BulkInsertAsync(GetUsers());

性能实测:

小结:
比原生EF Core快近三倍,并且兼容EF Core生态,对大项目极为友好!


五、SqlBulkCopy原生批量插入:极致性能之选 ⚡

SqlBulkCopy为SQL Server的原生批量复制API,是极致速度的代表,但代码略复杂。

using var bulkCopy = new SqlBulkCopy(ConnectionString);
bulkCopy.DestinationTableName = "dbo.Users";
// 映射字段
bulkCopy.ColumnMappings.Add(nameof(User.Email), "Email");
bulkCopy.ColumnMappings.Add(nameof(User.FirstName), "FirstName");
bulkCopy.ColumnMappings.Add(nameof(User.LastName), "LastName");
bulkCopy.ColumnMappings.Add(nameof(User.PhoneNumber), "PhoneNumber");
await bulkCopy.WriteToServerAsync(GetUsersDataTable());

DataTable生成代码略,可参考下方完整实现。

性能实测(全场最佳):


六、性能横向对比一览表

方法1001,00010,000100,0001,000,000
EF_OneByOne19.8 ms259.9 ms8,860.8 msN/AN/A
Dapper_Insert10.7 ms113.1 ms1,028 ms10,916 ms109,065 ms
EF_AddRange2.0 ms17.9 ms204 ms2,111 ms21,606 ms
BulkExtensions1.9 ms7.9 ms76 ms742 ms8,334 ms
SqlBulkCopy1.7 ms7.4 ms68 ms646 ms7,339 ms

七、场景推荐与选择建议

EF Core Bulk Extensions 并非完全免费,商业项目需购买许可证。

SqlBulkCopy 仅支持SQL Server,其他数据库请使用相应的批量插入API。

Dapper 适合轻量级项目,Apache 2.0许可证。


八、结论与互动 🏁

C#和EF Core在应对大规模数据插入时,其实可以“飞起来”!关键在于方法选择和代码实现的小细节。希望本文的实测与对比,能帮助你为自己的项目选到最合适的那把“利剑”。

如果你在生产环境中遇到过大批量数据导入的瓶颈,欢迎在评论区留言分享你的经验和踩过的坑!
你更倾向哪种方案?你的实际项目里有遇到什么“奇葩”需求吗?👇欢迎讨论&转发!



Next Post
轻松搞定.NET后台任务:Coravel实战详解