c# - 使用 C# 和 Npgsql 快速插入父表和子表

标签 c# postgresql npgsql

我使用的是 C#.NET 4.0 (Visual Studio 2010)、PostgreSQL 9.2 和 Npgsql 2.0.12。我无法升级到 Npgsql 3。

我需要对父表进行快速插入,然后使用该插入中的主键对子表进行快速插入。

父表有一个定义为“serial”的列,它是主键。

子表有一个整数列,它是返回父表的外键。

并非每个父记录都会有子记录。 parent 可以有 0 个、1 个或多个 child 。

目前我正在将父对象缓冲到一个列表中。当缓冲了 5000 个 parent 时,从线程池中产生一个新线程将记录写入数据库。 (创建了一个新列表 主线程缓冲下一组父对象。) 新线程调用 NpgsqlConnection.BeginTransaction(),然后在循环内调用带参数的 NpgsqlCommand.ExecuteScalar() 以插入父记录并取回主键。 然后构建父对象的子对象(如果有)并保存到另一个列表。在循环结束时提交 parent 的事务。但是这种方法非常缓慢。插入 5000 条记录需要 3 到 10 秒的时间。当然有更好的方法。

parent 提交后,我使用 http://codebetter.com/karlseguin/2009/10/25/postgresql-day-2/ 中描述的 BulkCopy (使用 NpgsqlCopyIn)插入子记录。这太棒了。它在不到半秒的时间内插入数千条子记录。

我也喜欢将 BulkCopy 用于父记录。但我不知道如何从批量插入中取回主键值。

那么使用 C# 和 Npgsql 快速插入父记录和子记录的技巧是什么?答案可能就在某处,但显然我没有使用正确的搜索引擎参数。

非常感谢。

最佳答案

当您使用serial 数据类型时,Postgres 会自动生成并分配一个序列。这很好,因为您可以劫持该序列用于其他目的,包括这个。

这是我的建议。

假设您的对象看起来像这样:

public Parent
{
    public long Id { get; set; }
    public string Description { get; set; }
    public List<Child> Children { get; set; }
}

public Child
{
    public long Id { get; set; }
    public long ParentId { get; set; }
    public string Description { get; set; }
}

让您的代码根据序列为每个父级分配一个 ID。这应该在眨眼之间发生:

NpgsqlCommand cmd = new NpgsqlCommand("select nextval('schema.foo_id_seq')", conn);
foreach (Parent p in parentList.Where(x => x.Id == null && x.Id == 0))
{
    p.Id = Convert.ToInt64(cmd.ExecuteScalar());
    p.Children.ForEach(x => x.ParentId = p.Id);
}

如果这些记录不存在,Where 子句可能并不重要……只是需要考虑一下。

从这里开始,您的 NpgsqlCopyIn 应该对 parent 和 child 来说都很棒。

关于c# - 使用 C# 和 Npgsql 快速插入父表和子表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41946686/

相关文章:

c# - 我的应用程序因 FileNotFoundException 而崩溃,我不明白为什么

c# - 奇怪的 HttpWebResponse 错误 : ServerProtocolViolation

postgresql - 嵌套查询作为 PostGIS 函数参数

c# - 如果参数在 IS 之后,Npgsql 会抛出错误

C# with Npgsql - 无法使用处理程序类型 Int32Handler 编写 CLR 类型 System.String

javascript - 由于空闲超时插件,页面加载事件多次触发?

c# - Linq 查询到 Lambda 表达式

postgresql - 如何使用 Struts 2 将数据插入 Postgres 数据库或从 Postgres 数据库检索数据?

windows - 如何为 Windows 安装 libpq-dev 包

mysql - 根据关联模型中的值对记录进行排序