在 NpgSql 中使用 BeginBinaryImport 插入位数据类型进行批量数据插入

Posted

技术标签:

【中文标题】在 NpgSql 中使用 BeginBinaryImport 插入位数据类型进行批量数据插入【英文标题】:In NpgSql Insert bit datatype using BeginBinaryImport for bulk data insertion 【发布时间】:2016-05-24 09:20:55 【问题描述】:

我一直在尝试使用 Npgsql 版本 3.1.2 为 postgre 数据库实现批量插入操作,但我遇到了一个问题('消息中留下的数据不足') 关于 postgre 表中列 paymentdone(bit(1)) 数据类型的数据类型未匹配。我曾尝试使用 bool、char、integer 数据类型(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);
    

【问题讨论】:

【参考方案1】:

这可能是因为当 Npgsql 看到一个布尔值时,它的默认值是发送一个 PostgreSQL 布尔值而不是一个 BIT(1)。使用二进制 COPY 时,您必须准确编写 PostgreSQL 期望的类型。

一种解决方案可能是使用 .NET BitArray 而不是布尔值。 Npgsql 将从该类型推断 PostgreSQL BIT() 并且一切都应该工作。

但更安全的解决方案是简单地调用StartRow(),然后使用接受NpgsqlDbType 的Write() 的重载。这使您可以明确指定要发送的 PostgreSQL 类型。

【讨论】:

以上是关于在 NpgSql 中使用 BeginBinaryImport 插入位数据类型进行批量数据插入的主要内容,如果未能解决你的问题,请参考以下文章

Npgsql使用1

无法使用实体框架找到或加载 Npgsql

Npgsql 如何处理失败的事务?

NPGSQL:使用 LWGEOMCOLLECTION 类型调用的关联操作

NpGsql EntityFramework 6 - “操作已经在进行中”

Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂