F# 中数据库记录的记录模式和类型不匹配
Mismatch in record pattern and type on database record in F#
如何修复以下错误?
此表达式的类型应为 'string * Nullable * Nullable' 但此处的类型为 'VisitType'(错误发生在"|AppointmentOnly(q.lastname, q.posting_time)).
和
字段'appointmentTime'不是静态的(错误发生在FsVisit.appointmentTime = q.appointment_time; ).
(这些错误发生在我尝试通过 WCF 从 PostgreSQL 数据库下载记录到 F# 客户端时)。
type VisitType =
| AppointmentOnly of name: string * postedTime: DateTime
| WalkIn of name: string * serviceTime: DateTime
| Kept of name: string * postedTime: DateTime * serviceTime: DateTime
| Open
type FsVisit =
{ appointmentTime: Nullable<DateTime>
visitType: VisitType }
with
member this.Name =
match this.visitType with
| AppointmentOnly(name=name) | WalkIn(name=name) | Kept(name=name) -> Some name
| Open -> None
let TestGetScheduleAsync (tableDate : DateTime) =
async {
let! data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map ( fun q ->
FsVisit.appointmentTime = q.appointment_time;
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(q.lastname, q.posting_time) -> AppointmentOnly({name = q.lastname; postedTime = q.posting_time})
| WalkIn(q.lastname, q.service_time) -> WalkIn({name =q.lastname; serviceTime = q.service_time})
| Kept(q.lastname, q.posting_time, q.service_time) -> Kept({name=q.lastname; postedTime = q.posting_time, serviceTime = q.service_time})
| Open -> None
)}
|> Async.StartAsTask
感谢您的帮助。
lastname
、posting_time
和 service_time
的元组不是 VisitType
类型的值。所以你不能将它与 VisitType
discriminated union cases 相匹配。我假设 posting_time
和 service_time
是 Nullable<DateTime>
值(与 appointment_time
相同)所以你应该将元组与元组匹配并根据 [=15 创建 VisitType
大小写=] 和 service_time
值(Some
或 None
)。我也会从匹配中删除名称
match (Option.ofNullable q.posting_time, Option.ofNullable q.service_time) with
| (Some postedTime, None) -> AppointmentOnly(q.lastname, postedTime)
| (None, Some serviceTime) -> WalkIn(q.lastname, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(q.lastname, postedTime, serviceTime)
| _ -> Open
如果您想要 VisitType option
,您可以通过为 Open
案例返回 None
和为其他案例返回 Some
来调整此代码。
请注意,如果您添加 active patterns,您的代码也可以编译,这将为您的输入数据(元组)创建所谓的命名分区:
let (|AppointmentOnly|WalkIn|Kept|Open|)
(name: string, postedTime: Nullable<DateTime>, serviceTime: Nullable<DateTime>) =
match (Option.ofNullable postedTime, Option.ofNullable serviceTime) with
| (Some postedTime, None) -> AppointmentOnly(name, postedTime)
| (None, Some serviceTime) -> WalkIn(name, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(name, postedTime, serviceTime)
| (None, None) -> Open
请记住,此处返回的 AppointementOnly
、WalkIn
、Kept
、Open
不是受歧视的联合案例 - 它是活动模式记录。现在您可以使用此活动模式将输入数据划分为分区并创建相应的 VisitType
个案例:
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
| WalkIn(name, serviceTime) -> WalkIn(name, serviceTime)
| Kept(name, postedTime, serviceTime) -> Kept(name, postedTime, serviceTime)
| Open -> Open
同样,这里我们在活动模式上进行匹配,然后创建一个可区分的联合:
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
^ ^
ACTIVE PATTERN IDENTIFIER UNION CASE
如何修复以下错误?
此表达式的类型应为 'string * Nullable * Nullable' 但此处的类型为 'VisitType'(错误发生在"|AppointmentOnly(q.lastname, q.posting_time)).
和
字段'appointmentTime'不是静态的(错误发生在FsVisit.appointmentTime = q.appointment_time; ).
(这些错误发生在我尝试通过 WCF 从 PostgreSQL 数据库下载记录到 F# 客户端时)。
type VisitType =
| AppointmentOnly of name: string * postedTime: DateTime
| WalkIn of name: string * serviceTime: DateTime
| Kept of name: string * postedTime: DateTime * serviceTime: DateTime
| Open
type FsVisit =
{ appointmentTime: Nullable<DateTime>
visitType: VisitType }
with
member this.Name =
match this.visitType with
| AppointmentOnly(name=name) | WalkIn(name=name) | Kept(name=name) -> Some name
| Open -> None
let TestGetScheduleAsync (tableDate : DateTime) =
async {
let! data = context.GetOfficeScheduleAsync(tableDate) |> Async.AwaitTask
return data |> Seq.map ( fun q ->
FsVisit.appointmentTime = q.appointment_time;
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(q.lastname, q.posting_time) -> AppointmentOnly({name = q.lastname; postedTime = q.posting_time})
| WalkIn(q.lastname, q.service_time) -> WalkIn({name =q.lastname; serviceTime = q.service_time})
| Kept(q.lastname, q.posting_time, q.service_time) -> Kept({name=q.lastname; postedTime = q.posting_time, serviceTime = q.service_time})
| Open -> None
)}
|> Async.StartAsTask
感谢您的帮助。
lastname
、posting_time
和 service_time
的元组不是 VisitType
类型的值。所以你不能将它与 VisitType
discriminated union cases 相匹配。我假设 posting_time
和 service_time
是 Nullable<DateTime>
值(与 appointment_time
相同)所以你应该将元组与元组匹配并根据 [=15 创建 VisitType
大小写=] 和 service_time
值(Some
或 None
)。我也会从匹配中删除名称
match (Option.ofNullable q.posting_time, Option.ofNullable q.service_time) with
| (Some postedTime, None) -> AppointmentOnly(q.lastname, postedTime)
| (None, Some serviceTime) -> WalkIn(q.lastname, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(q.lastname, postedTime, serviceTime)
| _ -> Open
如果您想要 VisitType option
,您可以通过为 Open
案例返回 None
和为其他案例返回 Some
来调整此代码。
请注意,如果您添加 active patterns,您的代码也可以编译,这将为您的输入数据(元组)创建所谓的命名分区:
let (|AppointmentOnly|WalkIn|Kept|Open|)
(name: string, postedTime: Nullable<DateTime>, serviceTime: Nullable<DateTime>) =
match (Option.ofNullable postedTime, Option.ofNullable serviceTime) with
| (Some postedTime, None) -> AppointmentOnly(name, postedTime)
| (None, Some serviceTime) -> WalkIn(name, serviceTime)
| (Some postedTime, Some serviceTime) -> Kept(name, postedTime, serviceTime)
| (None, None) -> Open
请记住,此处返回的 AppointementOnly
、WalkIn
、Kept
、Open
不是受歧视的联合案例 - 它是活动模式记录。现在您可以使用此活动模式将输入数据划分为分区并创建相应的 VisitType
个案例:
match (q.lastname, q.posting_time, q.service_time) with
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
| WalkIn(name, serviceTime) -> WalkIn(name, serviceTime)
| Kept(name, postedTime, serviceTime) -> Kept(name, postedTime, serviceTime)
| Open -> Open
同样,这里我们在活动模式上进行匹配,然后创建一个可区分的联合:
| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
^ ^
ACTIVE PATTERN IDENTIFIER UNION CASE