如何使用C#中的Dapper将数据发送到RECORD类型

时间:2018-04-09 18:03:55

标签: c# plsql dapper

我有一个PL / SQL程序,使用3个RECORD类型的变量作为参数,我必须填写我的数据(来自c#应用程序)来执行一个程序。

我试图通过c#与这些记录构建相同的结构,并通过Dapper作为参数传递,但由于dapper仅适用于标量数据类型,因此无法正常工作。

然后我试图将我的数据作为数组传递并将它们映射到过程中,但是RECORD类型不能接受像a.NAME := ('aaaaaa','sdasd');这样的数据集,它只能以这种方式工作:

a.NAME(1) := 'aaaaaa';
a.NAME(2) := 'sdasd';

我现在唯一想到的就是在程序文本中生成这样的字符串,但我觉得应该有更好的方法。怎么了?

P.S。毕竟我无法更改需要运行的脚本,所以我无法更改它接受的数据类型。

更新: 为了方便起见,让我们说,我已经决定做一个例子:

我们有2种自定义类型

TYPE A_REC IS RECORD (NAME dbms_sql.Varchar2_Table);
TYPE B_REC IS RECORD (NAME dbms_sql.Varchar2_Table
                         , ID dbms_sql.Number_Table);

和一个程序,可能会使用类似

的程序
declare
a c_pck.a_rec;
b c_pck.b_rec;
begin

a.NAME(1) := 'aaaaa';
b.NAME(1) := 'sssss';
b.NAME(2) := 'ddddd';
b.ID(1) := 111;
b.ID(2) := 222;


c_pck.pr(a => a, b => b);
end;

如何通过Dapper运行此程序?

2 个答案:

答案 0 :(得分:0)

我不能100%确定这是否适用于PL \ SQL,但是您可以将SQL表值参数传递到您从Dapper调用的存储过程中。 RECORD类型听起来像是一样的,所以它可能会起作用。

您需要使用DataTable来构建RECORD。您定义的列的顺序必须与它们在数据库中显示的顺序相匹配。

从以下链接:

var dt = new DataTable();
dt.Columns.Add("AUDIT_PK", typeof (long));
dt.Columns.Add("MESSAGE", typeof (string));
dt.Columns.Add("SUCCESS", typeof (bool));
dt.Rows.Add(1, "EHLO", null);

using (var conn = new SqlConnection("Data Source=.;Initial  Catalog=Scratch;Integrated Security=true"))
{
    conn.Open();
    conn.Execute("TestOne", new {TVP =   dt.AsTableValuedParameter("dbo.AUDITRECORD")}, commandType: CommandType.StoredProcedure);
}

https://www.codeproject.com/Articles/835519/Passing-Table-Valued-Parameters-with-Dapper

答案 1 :(得分:0)

你需要在这里处理两件事。

  1. 指示Oracle驱动程序了解您的自定义数据类型
  2. 在这里,你需要大量的样板。 您必须使用IOracleCustomType接口为UDT编写映射代码。 Here's官方文件。 This guide似乎是一个很好的资源。

    1. 指示Dapper了解您的自定义数据类型
    2. Dapper有一个映射到DbTypes的.NET类型的硬编码列表。 您可以添加到此列表,但仅添加到通用DbTypes。 要使用特定于数据库的功能,您的参数必须实现     SqlMapper.ICustomQueryParameter(这是表值的方式     SQL服务器工作的东西)。在AddParameter实现中,您可以手动构造OracleParameter并正确设置UDT类型名称。 Dapper应该正确处理返回值,因为这只是映射结果集,如