【发布时间】:2019-12-13 18:13:17
【问题描述】:
我正在尝试使用 ADO.NET 进行批量插入。到目前为止,我发现使用SqlDataAdapter 可能是一种方法。
我已经创建了包含 1 个表和 3 列的数据库以及将向该表中插入行的存储过程。
表PropertyTable:
Name: VARCHAR(10)
Number: INT
IsActive: BIT
存储过程InsertPropertyTable:
CREATE PROCEDURE InsertPropertyTable
@Par1 VARCHAR(10),
@Par2 INT,
@Par3 BIT
AS
BEGIN
INSERT INTO dbo.PropertyTable
VALUES (@Par1, @Par2, @Par3)
END
GO
C#代码:
namespace InsertManyTest.Console
{
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
var connString = "Server=.;Database=Test;Trusted_Connection=True;";
using (var connection = new SqlConnection(connString))
{
var adapter = new SqlDataAdapter("", connection);
var dataTable = new DataTable();
dataTable.Columns.AddRange(new[]
{
new DataColumn("Par1", typeof(string)),
new DataColumn("Par2", typeof(int)),
new DataColumn("Par3", typeof(bool))
});
adapter.InsertCommand = new SqlCommand("InsertPropertyTable", connection);
adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.DeleteCommand = new SqlCommand();
adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.UpdateCommand = new SqlCommand();
adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.SelectCommand = new SqlCommand();
adapter.SelectCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.InsertCommand.Parameters.Add("@Par1", SqlDbType.VarChar,10, "Par1");
adapter.InsertCommand.Parameters.Add("@Par2", SqlDbType.Int, 1, "Par2");
adapter.InsertCommand.Parameters.Add("@Par3", SqlDbType.Bit, 1, "Par3");
CreateRow(dataTable);
CreateRow(dataTable);
CreateRow(dataTable);
CreateRow(dataTable);
adapter.UpdateBatchSize = 2;
adapter.Update(dataTable);
}
}
private static void CreateRow(DataTable dataTable)
{
var row = dataTable.NewRow();
FillRow(row);
dataTable.Rows.Add(row);
}
private static void FillRow(DataRow row)
{
row["Par1"] = "Asd";
row["Par2"] = 1;
row["Par3"] = true;
}
}
}
当 UpdateBatchSize 设置为默认值 (1) 时,它可以工作,但每次插入都会进行往返。我想避免这种情况,所以我将UpdateBatchSize 设置为更大的值,但随后我得到了一些奇怪的异常:
System.ArgumentException: '指定的参数名称'Parameter1' 无效。'
来自adaper.Update(...);
我预计此更新会生成如下内容:
sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;
将在单次往返数据库中执行
更新: 我在堆栈溢出中发现了这个问题,作者正在对我做类似的事情。在他的情况下,它正在工作,他与其他批量插入的方法进行了比较
更新:
我是个笨笨笨的笨蛋。我在 .net core 2.2 中测试了这个,而不是在 .net 4.6.1 上。 它不适用于 .net core 2.2,但它适用于 .net 4.6.1。
我没有看到预期的结果,因为 sql server profiler 中有几行。每行包含一个exec ...。
【问题讨论】:
-
你确定在索引到
DataRow时参数名前面应该有@吗? -
@PalleDue 与
UpdateBatchSize=1一起使用,只要我更改它就会停止工作。
标签: c# .net sql-server .net-4.6.1