F# F中数据库记录的记录模式和类型不匹配#

F# F中数据库记录的记录模式和类型不匹配#,f#,pattern-matching,F#,Pattern Matching,如何修复以下错误 此表达式的类型应为'string*Nullable*Nullable',但此处的类型为'VisitType'(错误发生在“|仅任命(q.lastname,q.posting_time)) 及 字段“appointmentTime”不是静态的(FsVisit.appointmentTime=q.appointment\U time;上出现错误) (这些错误发生在我试图通过WCF将记录从PostgreSQL数据库下载到F#client时) type VisitType= |仅指定名

如何修复以下错误

此表达式的类型应为'string*Nullable*Nullable',但此处的类型为'VisitType'(错误发生在“|仅任命(q.lastname,q.posting_time))

字段“appointmentTime”不是静态的(FsVisit.appointmentTime=q.appointment\U time;上出现错误)

(这些错误发生在我试图通过WCF将记录从PostgreSQL数据库下载到F#client时)

type VisitType=
|仅指定名称:string*postedTime:DateTime
|名称:string*serviceTime:DateTime的演练
|保留名称:字符串*postedTime:DateTime*serviceTime:DateTime
|打开
类型FsVisit=
{appointmentTime:可为空
visitType:visitType}
具有
请告诉我你的名字=
将this.visitType与匹配
|仅任命(姓名=姓名)|步行(姓名=姓名)|保留(姓名=姓名)->某些姓名
|打开->无
让TestGetScheduleAync(tableDate:DateTime)=
异步的{
let!data=context.getOfficeScheduleAync(tableDate)|>Async.WaitTask
返回数据|>Seq.map(乐趣q->
FsVisit.appointmentTime=q.appointment\u时间;
将(q.lastname、q.posting\u time、q.service\u time)与
|AppointOnly(q.lastname,q.posting_time)->AppointOnly({name=q.lastname;postedTime=q.posting_time})
|WalkIn(q.lastname,q.service\u time)->WalkIn({name=q.lastname;serviceTime=q.service\u time})
|保留(q.lastname,q.posting\u time,q.service\u time)->保留({name=q.lastname;postedTime=q.posting\u time,serviceTime=q.service\u time})
|打开->无
)}
|>Async.startask

谢谢您的帮助。

lastname、
posting\u time
service\u time
的元组不是
VisitType
类型的值。因此您无法将其与
VisitType
区分的联合案例进行匹配。我假设
posting\u time
service\u time
可为空的值(与
appointment\u time
)相同,因此您应该将元组与元组匹配,并根据
posting\u time
service\u time
值(
Some
None
)创建
VisitType
大小写。我还将从匹配中删除名称

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选项
,您可以通过为
Open
案例返回
None
和为其他案例返回
Some
来调整此代码


请注意,如果您添加将为输入数据(元组)创建所谓命名分区的组件,那么您的代码也可以编译:

同样,我们在这里匹配活动模式,然后创建一个有区别的联合:

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

您正在尝试匹配元组
(q.lastname、q.posting\u time、q.service\u time)
您正在使用构造函数为类型
VisitType
创建。您打算如何处理
匹配
表达式?@Lee此代码是我使用的C类的一种提炼形式,我最终需要子类化和if/then语句来给出不同的行为,以确定访问是否为“WalkIn”“或仅指应用程序(等)。我的想法是,如果我能立即区分不同的访问类型,我最终会在分配行为时丢弃所有的if/then。我可能会大错特错,但这是一个很好的学习练习。非常感谢你向新手解释这一点。F#的学习曲线似乎比博客和教程显示的要陡峭得多。你的解释帮助我澄清了许多困惑。
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
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