Npgsql C#多行/值插入

时间:2019-06-18 21:05:41

标签: c# postgresql npgsql

我一直在看PostGres多行/值插入,在纯SQL中看起来像这样:

insert into table (col1, col2, col3) values (1,2,3), (4,5,6)....

我希望使用此功能的原因是我要插入大量通过队列到达的数据,我一次将其分批放入500/1000个记录插入中以提高性能。

但是,我一直无法在C#中找到执行此操作的示例,我所能找到的一切都是一次仅添加一个records参数,然后执行,这太慢了。

我目前正在使用Dapper进行此工作,但是我需要将SQL扩展到一个upsert(插入冲突更新),我发现的一切都表明Dapper无法处理。我发现有证据表明Postgres可以在单个action中处理增值和多值。

汤姆

3 个答案:

答案 0 :(得分:2)

我没有完全正确地回答你的问题。但是对于Postgresql中的批量插入,this is a good answer

它给出了一个示例,该示例将列表(RecordList)中的多个记录插入到表(user_data.part_list)中:

using (var writer = conn.BeginBinaryImport(
"copy user_data.part_list from STDIN (FORMAT BINARY)"))
{
    foreach (var record in RecordList)
    {
        writer.StartRow();
        writer.Write(record.UserId);
        writer.Write(record.Age, NpgsqlTypes.NpgsqlDbType.Integer);
        writer.Write(record.HireDate, NpgsqlTypes.NpgsqlDbType.Date);
    }

    writer.Complete();
}

答案 1 :(得分:0)

如果您想有效地插入许多记录,您可能想看看Npgsql's bulk copy API,它不使用SQL,是可用的最有效的选项。

否则,插入两行而不是一行并没有什么特别之处:

insert into table (col1, col2, col3) values (@p1_1,@p1_2,@p1_3), (@p2_1,@p2_2,@p_3)....

只需使用正确的名称添加参数并像执行其他任何SQL一样执行。

答案 2 :(得分:0)

COPY是最快的方法,但如果要使用ON CONFLICT ...子句进行UPSERTS,则不起作用。

如果有必要使用INSERT,则可以像使用n一样优雅地提取n行(每次调用可能会改变UNNEST

INSERT INTO table (col1, col2, ..., coln) SELECT UNNEST(@p1), UNNEST(@p2), ... UNNEST(@pn);

然后,参数p必须是匹配类型的数组。这是一个整数数组的示例:

new NpgsqlParameter()
{
 ParameterName = "p1",
 Value = new int[]{1,2,3},
 NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Integer
}