获取 Thoth.Json 可编码格式的查询结果

Get query result in Thoth.Json encodable format

我正在尝试从 table 中获取 id 列表作为 array/list 整数,然后使用 Thoth 对其进行编码并输出。

函数是

let listOfIds (columnId: int) =
    let ids = db.Query<int> $"Select id From table Where column = {columnId}"
    ids.ToArray //Tried AsList as well

调试器显示查询已连接且 ids 数组填充了正确的值,但调用时在编码器处生成异常:

module PageController
let loadHomePage =   
    let ids = module.listOfIds 2
    Encode.Auto.toString(4, ids)

例外情况:

System.TypeInitializationException: The type initializer for '<StartupCode$WebApplication>.$PageController' threw an exception.
 ---> System.Exception: Cannot generate auto encoder for Microsoft.FSharp.Core.FSharpFunc`2[[Microsoft.FSharp.Core.Unit, FSharp.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Int32[], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]. Please pass an extra encoder.
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1433.Invoke(String message) in F:\workspace\_work\s\src\fsharp\FSharp.Core\printf.fs:line 1433
   at Thoth.Json.Net.Encode.autoEncodeRecordsAndUnions(FSharpMap`2 extra, CaseStrategy caseStrategy, Boolean skipNullField, Type t)
   at Thoth.Json.Net.Encode.autoEncoder(FSharpMap`2 extra, CaseStrategy caseStrategy, Boolean skipNullField, Type t)
   at Thoth.Json.Net.Encode.Auto.generateEncoder[T](FSharpOption`1 caseStrategy, FSharpOption`1 extra, FSharpOption`1 skipNullField)
   at Thoth.Json.Net.Encode.Auto.toString[T](Int32 space, T value, FSharpOption`1 caseStrategy, FSharpOption`1 extra, FSharpOption`1 skipNullField)
   at <StartupCode$WebApplication>.$PageController..cctor() in C:\Users\dredgy\RiderProjects\WebApplication\WebApplication\PageController.fs:line 25
   --- End of inner exception stack trace ---
   at PageController.get_loadHomePage()
   at <StartupCode$WebApplication>.$Startup.Configure@25-1.Invoke(HttpContext context) in C:\Users\dredgy\RiderProjects\WebApplication\WebApplication\Startup.fs:line 26
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

问题是您的 listOfIds 函数没有 return 数字数组。它 return 是一个函数。

如果你问 IDE 你正在使用的 listOfIds 的类型是什么,它会告诉你这样的事情:

listOfIds : int -> (unit -> int array)

在最后一行,您显然打算对查询结果调用方法 .ToArray(),但您只是 引用了 它,将其转换为一个函数,然后returning 作为 listOfIds 的结果。此函数的类型为 unit -> int array,因此这就是 listOfIds 本身的结果。

然后您试图将其传递给 Encode.Auto.toString(无论是什么),它抱怨它不知道如何编码 F# 函数:

Cannot generate auto encoder for Microsoft.FSharp.Core.FSharpFunc...

要修复,请确保您确实通过给它参数调用 ToArray 方法。在这种情况下(我只能假设,因为我不知道 db 是什么),该方法有一个 unit 类型的参数,相当于 C# 中的“无参数”,所以这就是你应该传递的内容:

let listOfIds (columnId: int) =
    let ids = db.Query<int> $"Select id From table Where column = {columnId}"
    ids.ToArray()