在 NpgSql Insert bit 数据类型中使用 BeginBinaryImport 进行批量数据插入
In NpgSql Insert bit datatype using BeginBinaryImport for bulk data insertion
我一直在尝试使用 Npgsql 版本 3.1.2 为 postgre 数据库实现批量插入操作,但我遇到了一个问题 ('insufficient data left in message ')
关于 postgre table 中列 paymentdone(bit(1)) 数据类型的数据类型未匹配。我曾尝试使用 bool、char、整数数据类型 (C#),但也有同样的错误。
Code For bulk data insertion
public void BulkInsert(string connectionString, DataTable dataTable)
{
using (var npgsqlConn = new NpgsqlConnection(connectionString))
{
npgsqlConn.Open();
var commandFormat = string.Format(CultureInfo.InvariantCulture, "COPY {0} {1} FROM STDIN BINARY", "logging.testtable", "(firstName,LastName,LogDateTime,RowStatus,active,id,paymentdone)");
using (var writer = npgsqlConn.BeginBinaryImport(commandFormat))
{
foreach (DataRow item in dataTable.Rows)
{
writer.WriteRow(item.ItemArray);
}
}
npgsqlConn.Close();
}
}
DataTable Function
private static void BulkInsert()
{
DataTable table = new DataTable();
table.Columns.Add("firstName", typeof(String));
table.Columns.Add("LastName", typeof(String));
table.Columns.Add("LogDateTime", typeof(DateTime));
table.Columns.Add("RowStatus", typeof(int));
table.Columns.Add("active", typeof(bool));
table.Columns.Add("id", typeof(long));
table.Columns.Add("paymentdone", typeof(bool));
var dataRow = table.NewRow();
dataRow[0] = "Test";
dataRow[1] = "Temp";
dataRow[2] = DateTime.Now;
dataRow[3] = 1;
dataRow[4] = true;
dataRow[5] = 10;
dataRow[6] = true;
table.Rows.Add(dataRow);
BulkInsert(ConfigurationManager.ConnectionStrings["StoreEntities"].ConnectionString, table);
}
这可能是因为当 Npgsql 看到一个布尔值时,它的默认值是发送一个 PostgreSQL 布尔值而不是 BIT(1)。使用二进制 COPY 时,您必须准确编写 PostgreSQL 期望的类型。
一种解决方案可能是使用 .NET BitArray 而不是布尔值。 Npgsql 将从该类型推断出 PostgreSQL BIT() 并且一切正常。
但更安全的解决方案是简单地调用 StartRow()
,然后使用接受 NpgsqlDbType 的 Write()
的重载。这允许您明确指定要发送的 PostgreSQL 类型。
我一直在尝试使用 Npgsql 版本 3.1.2 为 postgre 数据库实现批量插入操作,但我遇到了一个问题 ('insufficient data left in message ') 关于 postgre table 中列 paymentdone(bit(1)) 数据类型的数据类型未匹配。我曾尝试使用 bool、char、整数数据类型 (C#),但也有同样的错误。
Code For bulk data insertion
public void BulkInsert(string connectionString, DataTable dataTable)
{
using (var npgsqlConn = new NpgsqlConnection(connectionString))
{
npgsqlConn.Open();
var commandFormat = string.Format(CultureInfo.InvariantCulture, "COPY {0} {1} FROM STDIN BINARY", "logging.testtable", "(firstName,LastName,LogDateTime,RowStatus,active,id,paymentdone)");
using (var writer = npgsqlConn.BeginBinaryImport(commandFormat))
{
foreach (DataRow item in dataTable.Rows)
{
writer.WriteRow(item.ItemArray);
}
}
npgsqlConn.Close();
}
}
DataTable Function
private static void BulkInsert()
{
DataTable table = new DataTable();
table.Columns.Add("firstName", typeof(String));
table.Columns.Add("LastName", typeof(String));
table.Columns.Add("LogDateTime", typeof(DateTime));
table.Columns.Add("RowStatus", typeof(int));
table.Columns.Add("active", typeof(bool));
table.Columns.Add("id", typeof(long));
table.Columns.Add("paymentdone", typeof(bool));
var dataRow = table.NewRow();
dataRow[0] = "Test";
dataRow[1] = "Temp";
dataRow[2] = DateTime.Now;
dataRow[3] = 1;
dataRow[4] = true;
dataRow[5] = 10;
dataRow[6] = true;
table.Rows.Add(dataRow);
BulkInsert(ConfigurationManager.ConnectionStrings["StoreEntities"].ConnectionString, table);
}
这可能是因为当 Npgsql 看到一个布尔值时,它的默认值是发送一个 PostgreSQL 布尔值而不是 BIT(1)。使用二进制 COPY 时,您必须准确编写 PostgreSQL 期望的类型。
一种解决方案可能是使用 .NET BitArray 而不是布尔值。 Npgsql 将从该类型推断出 PostgreSQL BIT() 并且一切正常。
但更安全的解决方案是简单地调用 StartRow()
,然后使用接受 NpgsqlDbType 的 Write()
的重载。这允许您明确指定要发送的 PostgreSQL 类型。