如何使用C# System.Data.Common.DbBatch类?
使用C# DbBatch类的核心要点与示例
一、DbBatch的本质:不用自己实现
DbBatch是抽象基类,你不需要手动继承实现它。针对SQL Server和Oracle,对应的官方ADO.NET驱动已经提供了具体实现:
- SQL Server:
SqlBatch(来自Microsoft.Data.SqlClient包) - Oracle:
OracleBatch(来自Oracle.ManagedDataAccess.Core包)
这些具体类已经封装了数据库的批量操作优化逻辑,直接调用即可。
二、SQL Server 批量插入示例(匹配你的单元测试场景)
替换原循环插入逻辑,用SqlBatch实现批量操作:
[TestMethod] public void Insert_Batch_SqlServer() { var sw = new Stopwatch(); sw.Start(); using (var conn = new SqlConnection(conn_string)) { conn.Open(); // 创建SqlBatch并关联连接 using var batch = new SqlBatch(conn); // 批量添加插入命令 for (int i = 0; i < numRecords; i++) { var cmd = new SqlBatchCommand("TEST_Insert") { CommandType = CommandType.StoredProcedure }; cmd.Parameters.Add(new SqlParameter("@TestParam1", i)); batch.BatchCommands.Add(cmd); } // 执行批量操作 var affectedRows = batch.ExecuteNonQuery(); sw.Stop(); Console.WriteLine($"Elapsed={sw.Elapsed}, Rows Affected={affectedRows}"); } }
三、Oracle 批量插入示例
针对Oracle使用OracleBatch,逻辑与SQL Server一致,仅需适配参数前缀与驱动类:
[TestMethod] public void Insert_Batch_Oracle() { var sw = new Stopwatch(); sw.Start(); using (var conn = new OracleConnection(conn_string)) { conn.Open(); using var batch = new OracleBatch(conn); for (int i = 0; i < numRecords; i++) { var cmd = new OracleBatchCommand("TEST_INSERT") { CommandType = CommandType.StoredProcedure }; cmd.Parameters.Add(new OracleParameter(":TestParam1", i)); // Oracle参数用冒号前缀 batch.BatchCommands.Add(cmd); } var affectedRows = batch.ExecuteNonQuery(); sw.Stop(); Console.WriteLine($"Elapsed={sw.Elapsed}, Rows Affected={affectedRows}"); } }
四、跨数据库通用写法(兼容SQL Server/Oracle)
如果需要一套代码适配两种数据库,可通过DbProviderFactory动态创建DbBatch:
[TestMethod] public void Insert_Batch_Generic() { var sw = new Stopwatch(); sw.Start(); // 根据数据库类型获取对应工厂类 DbProviderFactory factory = isSqlServer ? Microsoft.Data.SqlClient.SqlClientFactory.Instance : Oracle.ManagedDataAccess.Client.OracleClientFactory.Instance; using (var conn = factory.CreateConnection()) { conn.ConnectionString = conn_string; conn.Open(); // 创建DbBatch实例 using var batch = factory.CreateBatch(); batch.Connection = conn; for (int i = 0; i < numRecords; i++) { var cmd = factory.CreateBatchCommand(); cmd.CommandText = isSqlServer ? "TEST_Insert" : "TEST_INSERT"; cmd.CommandType = CommandType.StoredProcedure; // 创建适配数据库的参数 var param = factory.CreateParameter(); param.ParameterName = isSqlServer ? "@TestParam1" : ":TestParam1"; param.Value = i; cmd.Parameters.Add(param); batch.BatchCommands.Add(cmd); } var affectedRows = batch.ExecuteNonQuery(); sw.Stop(); Console.WriteLine($"Elapsed={sw.Elapsed}, Rows Affected={affectedRows}"); } }
五、关键注意事项
- 性能核心逻辑:DbBatch通过减少网络往返次数提升效率——原循环插入是单条请求多次网络传输,批量操作是多命令打包一次传输。
- 参数前缀差异:SQL Server用
@,Oracle用:,需严格区分。 - 驱动版本要求:确保安装最新官方驱动,
Microsoft.Data.SqlClient需2.0+版本,Oracle.ManagedDataAccess.Core需3.21+版本才支持DbBatch。 - 禁止自定义实现:官方驱动的具体类已经做了数据库专属优化,自行实现DbBatch不仅冗余,还可能导致性能损失。
内容的提问来源于stack exchange,提问作者Mr. Anderson
相关产品推荐
相关产品推荐

