本文介绍了记录模式和F#中数据库记录的类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何解决以下错误?

该表达式的类型应为'string * Nullable * Nullable',但此处的类型为'VisitType' ("|| AppointmentOnly(q.lastname)发生错误,q.posting_time)).

This expression was expected to have type 'string * Nullable * Nullable' but here has type 'VisitType' (Error occurs on "|AppointmentOnly(q.lastname, q.posting_time)).

字段"appointmentTime"不是静态的 (FsVisit.appointmentTime = q.appointment_time;发生错误).

Field 'appointmentTime' is not static (Error occurs on FsVisit.appointmentTime = q.appointment_time;).

(这些错误是在我尝试通过WCF从PostgreSQL数据库下载记录到F#客户端时发生的.

(These errors occur in my attempt to download records from a PostgreSQL database via WCF into F# client).

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

谢谢您的帮助.

推荐答案

lastnameposting_timeservice_time的元组不是VisitType类型的值.因此,您无法将其与VisitType有区别的工会案件相匹配.我假设posting_timeservice_timeNullable<DateTime>值(与appointment_time相同),因此您应该将元组与元组匹配,并根据posting_timeservice_time值创建VisitType大小写(SomeNone).我也会从匹配项中删除姓名

Tuple of lastname, posting_time, and service_time is not a value of VisitType type. So you cannot match it with VisitType discriminated union cases. I assume that posting_time and service_time are Nullable<DateTime> values (same as appointment_time) So you should match tuple with tuple and create VisitType case depending on posting_time and service_time value (Some or None). I also would remove name from matching

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.

You can adjust this code if you want VisitType option by returning None for Open case and Some for other cases.

请注意,如果您添加活动模式,它将为您的输入数据(元组)创建所谓的命名分区:

Note that your code can be compilable as well if you'll add active patterns which will create so-called named partitions for your input data (tuple):

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

请记住,此处返回的AppointementOnlyWalkInKeptOpen并非已区分的联合案例-它是活动模式记录.现在,您可以使用此活动模式将输入数据划分为多个分区,并创建相应的VisitType用例:

Keep in mind that AppointementOnly, WalkIn, Kept, Open returned here is not a discriminated union cases - it's an active pattern records. Now you can use this active pattern to divide your input data into partitions and create corresponding VisitType cases:

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

再次,在这里我们在活动模式上进行匹配,然后创建一个有区别的联合:

Again, here we are matching on the active pattern and then creating a discriminated union:

| AppointmentOnly(name, postedTime) -> AppointmentOnly(name, postedTime)
              ^                                    ^
     ACTIVE PATTERN IDENTIFIER                  UNION CASE

这篇关于记录模式和F#中数据库记录的类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-24 04:03