在C#开发中,当需要处理成百上千甚至上万条数据的数据库写入、更新或删除时,单条执行SQL语句的方式会频繁创建数据库连接、发送请求,导致性能严重下降,因此批量操作是处理大量数据的必要手段。不同的实现方式和工具库在效率、易用性上存在差异,开发者可以根据业务场景选择最合适的方案。

C#批量操作的常见实现方式
1. 原生ADO.NET拼接批量SQL
最基础的方式是通过ADO.NET拼接多条SQL语句,一次性发送给数据库执行。这种方式不需要引入额外依赖,适合简单的批量插入场景,但如果数据量过大,SQL语句长度会超出数据库限制,且拼接过程容易引发SQL注入风险。
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
public class BatchInsertDemo
{
public static void BatchInsertWithSql(List<User> userList)
{
string connectionString = "Server=127.0.0.1;Database=TestDb;User Id=sa;Password=123456;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
// 拼接批量插入SQL,每100条执行一次,避免SQL过长
int batchSize = 100;
for (int i = 0; i < userList.Count; i += batchSize)
{
var batch = userList.GetRange(i, Math.Min(batchSize, userList.Count - i));
string sql = "INSERT INTO Users (Name, Age, Email) VALUES ";
List<string> valueParts = new List<string>();
foreach (var user in batch)
{
valueParts.Add($"('{user.Name}', {user.Age}, '{user.Email}')");
}
sql += string.Join(",", valueParts);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
}
}
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
2. 使用SqlBulkCopy实现高效批量写入
SqlBulkCopy是.NET Framework提供的专门用于SQL Server大批量数据写入的类,它直接将数据流写入数据库,绕过了SQL语句解析的过程,效率远高于拼接SQL的方式,适合百万级数据的批量插入场景,仅支持SQL Server数据库。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
public class SqlBulkCopyDemo
{
public static void BulkInsertWithSqlBulkCopy(List<User> userList)
{
string connectionString = "Server=127.0.0.1;Database=TestDb;User Id=sa;Password=123456;";
// 将用户列表转换为DataTable
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Columns.Add("Email", typeof(string));
foreach (var user in userList)
{
DataRow dr = dt.NewRow();
dr["Name"] = user.Name;
dr["Age"] = user.Age;
dr["Email"] = user.Email;
dt.Rows.Add(dr);
}
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.DestinationTableName = "Users"; // 目标表名
bulkCopy.BatchSize = 10000; // 每批次写入的数据量
bulkCopy.WriteToServer(dt); // 执行批量写入
}
}
}
}
常用库的效率对比与选择
Entity Framework Core的批量操作
Entity Framework Core是常用的ORM框架,原生不支持高效的批量操作,单条Add后SaveChanges会生成多条插入语句。如果需要批量操作,可以引入EFCore.BulkExtensions扩展库,它封装了批量插入、更新、删除的逻辑,底层会根据数据库类型选择最优实现,支持SQL Server、MySQL等多种数据库,易用性高但效率略低于原生SqlBulkCopy。
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using EFCore.BulkExtensions;
public class EfCoreBulkDemo
{
public static void BulkInsertWithEfCore(List<User> userList, TestDbContext dbContext)
{
// 批量插入,扩展库会自动处理批量逻辑
dbContext.BulkInsert(userList);
// 批量更新
// dbContext.BulkUpdate(userList);
// 批量删除
// dbContext.BulkDelete(userList);
}
}
public class TestDbContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=127.0.0.1;Database=TestDb;User Id=sa;Password=123456;");
}
}
Dapper的批量操作
Dapper是轻量级ORM框架,性能接近原生ADO.NET,批量操作可以通过拼接SQL或者使用Dapper.Contrib扩展实现,也支持结合SqlBulkCopy使用。它的优势是灵活度高,开发者可以完全控制SQL逻辑,适合对性能有一定要求且需要自定义SQL的场景。
| 方案 | 适用场景 | 效率 | 数据库支持 |
|---|---|---|---|
| 原生ADO.NET拼接SQL | 小批量数据、简单场景 | 较低 | 所有数据库 |
| SqlBulkCopy | SQL Server大批量数据写入 | 最高 | 仅SQL Server |
| EFCore.BulkExtensions | 使用EF Core的项目、多数据库支持 | 较高 | 多种数据库 |
| Dapper批量操作 | 轻量级ORM项目、自定义SQL需求 | 较高 | 所有数据库 |
批量操作的注意事项
- 批量操作时需要控制单批次的数据量,避免单次操作占用过多数据库资源,导致锁表或超时。
- 执行批量操作前建议关闭数据库的自动提交,操作完成后手动提交,减少事务开销。
- 如果使用参数化拼接SQL,需要注意参数数量不能超过数据库的限制,比如SQL Server单条语句最多支持2100个参数。
- 批量更新和删除操作建议先加WHERE条件测试,避免误删或误改全表数据。
如果是SQL Server场景下的大批量数据写入,优先选择SqlBulkCopy;如果使用EF Core开发且需要多数据库兼容,选择EFCore.BulkExtensions;如果是轻量级项目且需要灵活控制SQL,Dapper是更合适的选择。
C#批量操作数据库Entity_FrameworkSqlBulkCopy修改时间:2026-07-21 17:09:17