使用 Dapper (C#) 调用 PostgreSQL 存储过程
Posted
技术标签:
【中文标题】使用 Dapper (C#) 调用 PostgreSQL 存储过程【英文标题】:Using Dapper (C#) to call PostgreSQL stored procedure 【发布时间】:2020-12-07 16:59:10 【问题描述】:我发布这个有两个原因
-
我是 PostgreSQL 新手,将这些信息拼凑起来需要一段时间,所以我认为其他人会觉得这很有帮助,并且
询问是否有另一种方法来调用 PostgreSQL 存储过程,不需要将所有参数都包含在存储过程名称/签名中。
下面使用 Dapper 和 Npgsql 调用一个 PostgreSQL 存储过程,插入(传入的空 id_inout)或更新记录(id_inout 有一个值)。
我想了解为什么 PostgreSQL 在进行调用时需要整个存储过程签名。
public static int? PO_Save(PurchaseOrder po)
int? recordId = null;
using (var cn = new NpgsqlConnection(AppSettings.ConnectionString))
if (cn.State != ConnectionState.Open)
cn.Open();
var procName = "CALL po_save(@in_ponumber,@in_deliverydate,@in_bldnum," +
"@in_facname,@in_facnumber,@in_facaddress1,@in_facaddress2,@in_city," +
"@in_state,@in_zip,@in_theme,@id_inout)";
var p = new Dapper.DynamicParameters();
p.Add("@in_ponumber", po.PONumber);
p.Add("@in_deliverydate", po.DeliveryDate);
p.Add("@in_bldnum", po.BldNum);
p.Add("@in_facname", po.FacName);
p.Add("@in_facnumber", po.FacNumber);
p.Add("@in_facaddress1", po.FacAddress1);
p.Add("@in_facaddress2", po.FacAddress2);
p.Add("@in_city", po.City);
p.Add("@in_state", po.State);
p.Add("@in_zip", po.Zip);
p.Add("@in_theme", po.Theme);
p.Add("@id_out", po.POID, null, ParameterDirection.InputOutput);
var res = cn.Execute(procName, p);
recordId = p.Get<int>("@id_inout");
return recordId;
【问题讨论】:
【参考方案1】:您应该能够将commandType: CommandType.StoredProcedure
传递给Execute
,例如:
var res = cn.Execute(
"po_save",
new
in_ponumber = po.PONumber,
in_deliverydate = po.DeliveryDate,
// etc...
,
commandType: CommandType.StoredProcedure,
);
这是带有此类示例的文档:https://github.com/StackExchange/Dapper/blob/main/Readme.md#stored-procedures
【讨论】:
不幸的是,对于 PostgreSQL,CommandType.StoredProcedure 是为函数保留的 “请注意,CommandType.StoredProcedure 将生成一个 SELECT 命令 - 适用于函数 - 而不是适用于过程的 CALL 命令。 [...] 调用存储过程的唯一方法是编写自己的 CALL my_proc(...) 命令,无需设置 CommandBehavior.StoredProcedure。” (npgsql.org/doc/basic-usage.html#stored-functions-and-procedures)。尝试设置 CommandType 会导致以下异常 - Npgsql.PostgresException: 42809: proc-name () ... is an procedure.以上是关于使用 Dapper (C#) 调用 PostgreSQL 存储过程的主要内容,如果未能解决你的问题,请参考以下文章
Dapper use Table Value Parameter in C# (Sql Server 数组参数)