记录模式和F#中数据库记录的类型不匹配 [英] Mismatch in record pattern and type on database record in F#

查看:154
本文介绍了记录模式和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#中数据库记录的类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆