我在postgresql中有两个SQL函数(过程)。他们拿走并返回阵列;他们的签名是
create function arr_ret( x int) returns int[] as
和
create function arr_param( x int[] ) returns int as
执行时的第一个函数返回
> ctx.Functions.ArrRet.Invoke(6);;
Executing SQL : EXEC arr_ret(6) - params
val it : Unit = ()
>
可以看出,调用操作的签名是Unit()=();没有任何回报。我原本期望Unit()= int list,因为期望该过程返回一个整数数组。
执行时的第二个功能
> ctx.Functions.ArrParam.Invoke( [1;2;3;4;5;6] );;
ctx.Functions.ArrParam.Invoke( [1;2;3;4;5;6] );;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(22,1): error FS0501: The member or object constructor 'Invoke' takes 0 argument(s) but is here given 1. The requir
ed signature is 'SqlDataProvider<...>.dataContext.Functions.ArrParam.Result.Invoke() : SqlDataProvider<...>.dataContext.
Functions.ArrParam.Result.SprocResult'.
Npgsql没有看到数组类型的参数(输入或输出)。文档说3.0g版本支持postgresql数组和复合类型,我使用的是最新的3.2.3
答案 0 :(得分:1)
您正在将一个类型为FSharpList
的参数发送到需要params的方法中。您使用它的方式将整个列表作为单个参数发送。
ctx.Functions.ArrParam.Invoke(1, 2, 3, 4, 5, 6);;
以上将根据需要单独发送,但如果您通过整个集合则不会。原因是类型提供程序正在尝试解析对象的类型,而不是将整个数组视为多个参数。 在C#中,这样可以正常工作,但不能在F#中工作。
这是一种很好的测试方法。
在C#中定义此方法:
public static void PrintArgs(params object[] args)
{
foreach (var arg in args)
{
Console.WriteLine($"Type: {arg.GetType().Name}");
}
}
在F#中将其称为:
PrintArgs(1, 2.0, true, "4")
PrintArgs([1; 2; 3; 4])
他们导致:
>
Type: Int32
Type: Double
Type: Boolean
Type: String
val it : unit = ()
>
Type: FSharpList`1
val it : unit = ()
>
你的问题是在第二次调用中发生的事情,它实际上是一个正在发送的List而不是多个参数。