【问题标题】:Get query result in Thoth.Json encodable format以 Thoth.Json 可编码格式获取查询结果
【发布时间】:2021-04-05 01:46:35
【问题描述】:

我试图从表中获取一个 id 列表作为整数数组/列表,然后用 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\1\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)

【问题讨论】:

  • 当您的问题是异常或错误时,一个好的做法是将异常/错误的全文粘贴到问题正文中,这样尝试回答的人就不必猜测了。
  • 第一篇文章中已经添加了,就是类型不想被编码。它在使用 type x={id:int} 的自定义类型时确实有效,但因为我只想要一个 [1, 2, 3] 的 id 列表,所以这不是一个理想的解决方案。

标签: f# f#-data


【解决方案1】:

问题是您的listOfIds 函数没有返回数字数组。而是返回一个函数。

如果您询问您正在使用的任何 IDE,listOfIds 的类型是什么,它会告诉您如下信息:

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

在最后一行,您显然打算在查询结果上调用方法 .ToArray(),但您只是引用它,将其转换为函数并作为 listOfIds 的结果返回.这个函数的类型是unit -&gt; 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()

【讨论】:

  • 该死的。干杯。必须仔细检查这不是转录错误。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
相关资源
最近更新 更多