C# 使用ADO.NET的批处理操作

C# 使用ADO.NET的批处理操作,c#,.net,sql-server,.net-4.6.1,C#,.net,Sql Server,.net 4.6.1,我正在尝试使用ADO.NET进行批插入。到目前为止,我发现使用SqlDataAdapter可能是一种方法 我已经创建了一个包含1个表和3列的数据库,以及将向该表中插入行的存储过程 表属性表: Name: VARCHAR(10) Number: INT IsActive: BIT CREATE PROCEDURE InsertPropertyTable @Par1 VARCHAR(10), @Par2 INT, @Par3 BIT AS BEGIN INSERT

我正在尝试使用ADO.NET进行批插入。到目前为止,我发现使用
SqlDataAdapter
可能是一种方法

我已经创建了一个包含1个表和3列的数据库,以及将向该表中插入行的存储过程

属性表

Name: VARCHAR(10)
Number: INT
IsActive: BIT
CREATE PROCEDURE InsertPropertyTable
    @Par1 VARCHAR(10),
    @Par2 INT,
    @Par3 BIT
AS
BEGIN
    INSERT INTO dbo.PropertyTable
    VALUES (@Par1, @Par2, @Par3)
END
GO
存储过程
InsertPropertyTable

Name: VARCHAR(10)
Number: INT
IsActive: BIT
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
{
使用制度;
使用系统数据;
使用System.Data.SqlClient;
班级计划
{
静态void Main(字符串[]参数)
{
var connString=“服务器=;数据库=测试;受信任的_连接=真;”;
使用(var连接=新的SqlConnection(connString))
{
var adapter=新的SqlDataAdapter(“,连接);
var dataTable=新的dataTable();
dataTable.Columns.AddRange(新[]
{
新数据列(“Par1”,类型(字符串)),
新数据列(“Par2”,typeof(int)),
新数据列(“Par3”,类型(bool))
});
adapter.InsertCommand=newsqlcommand(“InsertPropertyTable”,connection);
adapter.InsertCommand.CommandType=CommandType.StoredProcess;
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=newsqlcommand();
adapter.SelectCommand.UpdatedRowSource=UpdateRowSource.None;
Add(“@Par1”,SqlDbType.VarChar,10,“Par1”);
Add(“@Par2”,SqlDbType.Int,1,“Par2”);
Add(“@Par3”,SqlDbType.Bit,1,“Par3”);
CreateRow(数据表);
CreateRow(数据表);
CreateRow(数据表);
CreateRow(数据表);
adapter.UpdateBatchSize=2;
adapter.Update(数据表);
}
}
私有静态void CreateRow(DataTable DataTable)
{
var row=dataTable.NewRow();
FillRow(世界其他地区);
dataTable.Rows.Add(行);
}
私有静态void FillRow(数据行)
{
行[“Par1”]=“Asd”;
行[“Par2”]=1;
行[“Par3”]=真;
}
}
}
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;
这将在到数据库的一次往返中执行


更新: 我在stack overflow上发现了这个问题,作者也在做类似的事情。在他的案例中,它是有效的,他将其与其他批量插入方法进行了比较


更新:

我是个笨蛋。我是在.NETCore2.2中测试的,而不是在.NET4.6.1中。 它在.NETCore2.2上不起作用,但在.NET4.6.1上起作用


我并没有看到预期的结果,因为SQLServer探查器中有几行。每行包含一个
exec…

似乎可以使用表值参数

基本上,您可以在SQL Server端创建新的自定义类型,该类型反映要发送到存储过程的数据结构(一行)。然后,使用该类型通知存储过程接受的参数类型。一旦在存储过程中收到该参数,就可以像查询任何其他表一样查询该表值参数:例如,从中选择所有内容并插入到实际表中

参考文献1:


参考文献2:

我知道
UserDefinedType
会起作用,但要做到这一点需要付出额外的努力。另外,如果您想插入一行,您必须假装您有一个集合或单独的存储过程。当索引到
数据行时,您必须确保参数名称前面应该有
@
?@PalleDue使用
UpdateBatchSize=1
,并且每当我更改它时就会停止工作。