f# - 如何将数据库记录读入有区别的联合?
问题描述
假设我在 F# 中有以下内容:
type PersonName = {
birthDate : DateTime
firstName : string
lastName : string
}
其次是有区别的工会:
type Visit =
| Scheduled of name: PersonName * appointmentTime: DateTime
| WalkIn of name: PersonName * appointmentTime: DateTime * timeOfService: DateTime
| KeptAppointment of name: PersonName * appointmentTime: DateTime * postingTime: DateTime * serviceTime: DateTime
| OpenSlot of appointmentTime: DateTime
with
member x.Name =
match x with
| Scheduled(name, _)
| WalkIn(name, _, _)
| KeptAppointment(name, _, _, _) -> Some name
| OpenSlot _ -> None
如果 Visit 被定义为一个简单的记录,例如:
type Visit = {
lastName : string
firstName : string
birthDate : DateTime
appointmentTime : Nullable<DateTime>
tservice : Nullable<DateTime>
postingTime : Nullable<DateTime>
chartNumber : Nullable<int>
}
然后从数据库服务器读取的以下内容正常工作:
/// Get the office schedule for the tableDate.
let GetScheduleAsync (tableDate : DateTime) =
async {
let! data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map(fun q -> {
Visit.lastName = q.lastname
firstName = q.firstname
birthDate = q.birthdate
appointmentTime = q.appointment_time
tservice = q.service_time
postingTime = q.posting_time
chartNumber = q.chart_number
})
}
|> Async.StartAsTask
但是,如果使用第一个版本的 Visit(区分联合),“编译器”无法识别如何处理 PersonName 的生日、名字和姓氏。显然,我没有正确传达我的意图。
那么,如何将数据库记录读入有区别的联合呢?
解决方案
有许多不同的方法可以做到这一点;所有这些都与大多数 ORM 处理继承类的方式非常相似。然而,考虑到这些天数据库的状态,还有其他方法。
从根本上说,所有联合都是由给定“标签”调度的一组类型。对于每个标签/联合案例,都有一组必须定义的字段(记录)。因此,您需要在 map lambda 中检查某种条件并适当地创建正确的联合类型。
let GetScheduleAsync (tableDate : DateTime) =
async {
let! data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map(fun q ->
match q.Tag with
| x when x = "Scheduled" -> Scheduled({ firstName = q.firstName; lastName = q.lastName; birthDate = q.BirthDate }, q.appointmentTime)
| _ -> failwithf "Insert other cases here"
)
}
|> Async.StartAsTask
如何确定“标签”实际上是数据库设计的问题,并且有许多不同的策略可以做到这一点(例如,带有标签字段的单个表,每个具体类/标签的表)。一些数据库还允许 JSON 序列化(例如 Postgres),如果您只想将联合直接序列化/反序列化到字段中,这可以是一个选项。如何表示数据库中的数据以及如何将其读入联合构造函数完全取决于您。
推荐阅读
- php - Laravel 日期时间问题
- content-management-system - 使用动态内容制作增强现实
- ruby-on-rails - 带状充电的未定义变量“游戏”
- python - 无法抓取乐天金融数据
- ssl - 如何使用 cloudflare 使服务器上的 API 安全(HTTPS)
- for-loop - for 循环中的 golang 范围是否保证只评估一次?
- amazon-web-services - 使用 Route53 从一个域重定向到另一个域
- python - 无法完成 python 设置 - 导致问题的子进程文件
- html - 模态窗口不可滚动
- json - 未处理的异常:FormatException:意外字符(在字符 1 处)