gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 14:40:08 24 4
gpt4 key购买 nike

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

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

属性表:

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: 'Specified parameter name 'Parameter1' is not valid.'

来自 adaper.Update(...);

我预计此更新会生成如下内容:

sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;
sp_exec InsertPropertyTable 'Asd', 1;

这将在数据库的单次往返中执行


更新:我在堆栈溢出上发现了这个问题,作者正在对我做类似的事情。在他的例子中,它正在工作,他与其他批量插入方式进行了比较

Bulk insert using SP

Blog post from 2008


更新:

我是个笨蛋。我是在 .net core 2.2 而不是 .net 4.6.1 上测试的。它不适用于 .net core 2.2,但它有点适用于 .net 4.6.1。

我没有看到预期的结果,因为 sql server profiler 中有几行。每行包含单个 exec ...

最佳答案

看来您可能会使用表值参数。

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

引用 1:https://learn.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine?view=sql-server-2017

引用 2:https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters

关于c# - 使用 ADO.NET 的批处理操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57371841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com