使用参数进行简单插入
您的项目将需要引用以下程序集:Npgsql
。如果此引用在以下范围内不可见视觉工作室, then:
- 浏览到连接器的安装文件夹
- 执行:
GACInstall.exe
- Restart 视觉工作室.
样本表
CREATE TABLE "OrderHistory"
(
"OrderId" bigint NOT NULL,
"TotalAmount" bigint,
CONSTRAINT "OrderIdPk" PRIMARY KEY ("OrderId")
)
WITH (
OIDS=FALSE
);
ALTER TABLE "OrderHistory"
OWNER TO postgres;
GRANT ALL ON TABLE "OrderHistory" TO postgres;
GRANT ALL ON TABLE "OrderHistory" TO public;
ALTER TABLE "OrderHistory" ALTER COLUMN "OrderId" SET (n_distinct=1);
GRANT SELECT("OrderId"), UPDATE("OrderId"), INSERT("OrderId"), REFERENCES("OrderId") ON "OrderHistory" TO public;
GRANT SELECT("TotalAmount"), UPDATE("TotalAmount"), INSERT("TotalAmount"), REFERENCES("TotalAmount") ON "OrderHistory" TO public;
示例代码
请务必使用以下指令:
using Npgsql;
using NpgsqlTypes;
在您的方法中输入以下源代码:
// Make sure that the user has the INSERT privilege for the OrderHistory table.
NpgsqlConnection connection = new NpgsqlConnection("PORT=5432;TIMEOUT=15;POOLING=True;MINPOOLSIZE=1;MAXPOOLSIZE=20;COMMANDTIMEOUT=20;COMPATIBLE=2.2.4.3;DATABASE=test;HOST=127.0.0.1;PASSWORD=test;USER ID=test");
connection.Open();
DataSet dataSet = new DataSet();
NpgsqlDataAdapter dataAdapter = new NpgsqlDataAdapter("select * from OrderHistory where OrderId=-1", connection);
dataAdapter.InsertCommand = new NpgsqlCommand("insert into OrderHistory(OrderId, TotalAmount) " +
" values (:a, :b)", connection);
dataAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("a", NpgsqlDbType.Bigint));
dataAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("b", NpgsqlDbType.Bigint));
dataAdapter.InsertCommand.Parameters[0].Direction = ParameterDirection.Input;
dataAdapter.InsertCommand.Parameters[1].Direction = ParameterDirection.Input;
dataAdapter.InsertCommand.Parameters[0].SourceColumn = "OrderId";
dataAdapter.InsertCommand.Parameters[1].SourceColumn = "TotalAmount";
dataAdapter.Fill(dataSet);
DataTable newOrders = dataSet.Tables[0];
DataRow newOrder = newOrders.NewRow();
newOrder["OrderId"] = 20;
newOrder["TotalAmount"] = 20.0;
newOrders.Rows.Add(newOrder);
DataSet ds2 = dataSet.GetChanges();
dataAdapter.Update(ds2);
dataSet.Merge(ds2);
dataSet.AcceptChanges();
connection.Close();
对性能的思考
最初的帖子没有提及性能要求。要求解决方案必须:
- 使用插入
DataTable
- 不使用循环插入数据
如果您要插入大量数据,那么我建议您查看一下性能选项。这Postgres文档建议您:
- 禁用自动提交
- Use the
COPY
command
- 删除索引
- 删除外键约束
- etc.
有关优化 Postgres 插入的更多信息,请查看:
- PostgresSql.org:插入数据 http://www.postgresql.org/docs/9.1/static/dml-insert.html
- PostgresSql.org:插入 + 性能提示 http://www.postgresql.org/docs/9.1/static/populate.html
- StackOverflow:如何加快 PostgreSQL 中的插入性能 https://stackoverflow.com/questions/12206600/how-to-speed-up-insertion-performance-in-postgresql
此外,还有许多其他因素会影响系统的性能。有关高级介绍,请查看:
-
ADO.NET SQL Server Performance bottleneck https://stackoverflow.com/a/21769502/949681
- 这篇文章概述了优化性能的一般(即非 SqlServer)策略。
其他选项
- Does the .NET connector support the Postgres
Copy
command?
- 如果没有,您可以下载源代码 http://npgsql.projects.pgfoundry.org/为了
Npgsql
连接器并添加您自己的BulkCopy()
方法。请务必首先查看源代码的许可协议。
- Check to see if Postgres supports Table Value Parameters.
- 这种方法允许您将表传递到
Postgres
然后可以将数据直接插入目标的函数。
- 购买一个Postgres来自供应商的 .NET 连接器,其中包含所需的功能。
附加参考资料
-
Postgres .NET 连接器 http://npgsql.projects.pgfoundry.org/ - free & 开源