如何修复 Giraffe API 通过 SqlDataProvider 从数据库获取的空对象
How to fix empty objects returned by Giraffe API fetched from DB through SqlDataProvider
我正在尝试通过创建一个带有存储库的 F# 应用程序来学习 F#,以便为将来的 Gym 应用程序获取练习。
我使用 SqlServer 存储数据并使用 Fsharp.Data.Sql 获取数据。这个单元测试工作得很好。
我正在尝试使用 Giraffe 通过 Web api 公开数据,问题是我得到了一个长度正确但里面有空对象的列表。
上下文如下:
module Context
open FSharp.Data.Sql
let [<Literal>] dbVendor = Common.DatabaseProviderTypes.MSSQLSERVER
let [<Literal>] connectionString = "Server=DESKTOP-20JMHNK;Database=GymStrongDB;Trusted_Connection=True;"
let [<Literal>] indivAmount = 1000
let [<Literal>] useOptTypes = true
let [<Literal>] owner = "public, admin, references"
type sql =
SqlDataProvider<
dbVendor,
connectionString,
"",
"",
indivAmount,
useOptTypes,
owner>
let gymStrongContext = sql.GetDataContext()
这是存储库
namespace GymStrong.Repositories
open ...
module ExerciseRepository =
let ctx = gymStrongContext.Dbo
let getExercises =
ctx.Exercises |> Seq.toList
let getExercisesHandler : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
Successful.OK getExercises next ctx
这里是Program.fs
的相关部分
open ...
let webApp =
choose [
GET >=>
choose [
route "/" >=> text "Hello World"
route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
route "/logout" >=> mustBeLoggedIn >=> logoutHandler
route "/exercises" >=> mustBeLoggedIn >=> getExercisesHandler
]
POST >=>
choose [
route "/register" >=> registerHandler
route "/login" >=> loginHandler
]
]
在单元测试中,这可以正常工作。单元测试是用 C# 编写的。
当我通过 PostMan 使用 API 时,我收到此响应
[{},{}]
长度正确,因为我在数据库中有两个练习,但对象似乎是空的。
这可能对某人有用,所以我会 post。
Giraffe 和 SqlDataProvider 都在做他们应该做的事情。问题是我认为我可以将提供的类型作为 json-响应传递给 API。这是错误的,因为提供的类型不是真正的类型,而是 "erased"(而不是我认为我正在使用的类型 Generated)。
为了解决这个问题,我需要将值映射到 "real" 贫乏的 DTO 对象并将其作为响应传递。现在我需要弄清楚是否可以提供这些基于实体类型的贫血 DTO 对象,并让它们从其他程序集中生成和使用。
附加代码:
在repository/service
type exerciseDto = {
Id : string;
Name : string;
Description : string;
Owner : string;
Type : int;
}
let getExercises =
ctx.Exercises |> Seq.map(fun exercise -> exercise.MapTo<exerciseDto>()) |> Seq.toList
并且在program.cs
let handlerWrapper action : HttpHandler =
fun (next : HttpFunc) (ctxHttp : HttpContext) ->
Successful.OK action next ctxHttp
let webApp =
choose [
GET >=>
choose [
route "/" >=> text "Hello World"
route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
route "/logout" >=> mustBeLoggedIn >=> logoutHandler
route "/exercises" >=> mustBeLoggedIn >=> handlerWrapper getExercises
]
POST >=>
choose [
route "/register" >=> registerHandler
route "/login" >=> loginHandler
]
]
希望这可以帮助任何人在未来节省时间。我至少花了几个小时。
我正在尝试通过创建一个带有存储库的 F# 应用程序来学习 F#,以便为将来的 Gym 应用程序获取练习。
我使用 SqlServer 存储数据并使用 Fsharp.Data.Sql 获取数据。这个单元测试工作得很好。
我正在尝试使用 Giraffe 通过 Web api 公开数据,问题是我得到了一个长度正确但里面有空对象的列表。
上下文如下:
module Context
open FSharp.Data.Sql
let [<Literal>] dbVendor = Common.DatabaseProviderTypes.MSSQLSERVER
let [<Literal>] connectionString = "Server=DESKTOP-20JMHNK;Database=GymStrongDB;Trusted_Connection=True;"
let [<Literal>] indivAmount = 1000
let [<Literal>] useOptTypes = true
let [<Literal>] owner = "public, admin, references"
type sql =
SqlDataProvider<
dbVendor,
connectionString,
"",
"",
indivAmount,
useOptTypes,
owner>
let gymStrongContext = sql.GetDataContext()
这是存储库
namespace GymStrong.Repositories
open ...
module ExerciseRepository =
let ctx = gymStrongContext.Dbo
let getExercises =
ctx.Exercises |> Seq.toList
let getExercisesHandler : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
Successful.OK getExercises next ctx
这里是Program.fs
的相关部分open ...
let webApp =
choose [
GET >=>
choose [
route "/" >=> text "Hello World"
route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
route "/logout" >=> mustBeLoggedIn >=> logoutHandler
route "/exercises" >=> mustBeLoggedIn >=> getExercisesHandler
]
POST >=>
choose [
route "/register" >=> registerHandler
route "/login" >=> loginHandler
]
]
在单元测试中,这可以正常工作。单元测试是用 C# 编写的。
当我通过 PostMan 使用 API 时,我收到此响应
[{},{}]
长度正确,因为我在数据库中有两个练习,但对象似乎是空的。
这可能对某人有用,所以我会 post。
Giraffe 和 SqlDataProvider 都在做他们应该做的事情。问题是我认为我可以将提供的类型作为 json-响应传递给 API。这是错误的,因为提供的类型不是真正的类型,而是 "erased"(而不是我认为我正在使用的类型 Generated)。
为了解决这个问题,我需要将值映射到 "real" 贫乏的 DTO 对象并将其作为响应传递。现在我需要弄清楚是否可以提供这些基于实体类型的贫血 DTO 对象,并让它们从其他程序集中生成和使用。
附加代码:
在repository/service
type exerciseDto = {
Id : string;
Name : string;
Description : string;
Owner : string;
Type : int;
}
let getExercises =
ctx.Exercises |> Seq.map(fun exercise -> exercise.MapTo<exerciseDto>()) |> Seq.toList
并且在program.cs
let handlerWrapper action : HttpHandler =
fun (next : HttpFunc) (ctxHttp : HttpContext) ->
Successful.OK action next ctxHttp
let webApp =
choose [
GET >=>
choose [
route "/" >=> text "Hello World"
route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
route "/logout" >=> mustBeLoggedIn >=> logoutHandler
route "/exercises" >=> mustBeLoggedIn >=> handlerWrapper getExercises
]
POST >=>
choose [
route "/register" >=> registerHandler
route "/login" >=> loginHandler
]
]
希望这可以帮助任何人在未来节省时间。我至少花了几个小时。