【发布时间】:2016-10-08 00:43:27
【问题描述】:
我有一个相对简单的带有连接的F# 查询表达式:
let mdrQuery =
query {
for header in db.CustomerDetails do
leftOuterJoin row in db.MDR_0916
on (header.PID = row.PID) into result
select (result, header)
}
这会返回每个header 和result,但对于在row 中不匹配的header,result 只是一个空序列,当查询结果传递给自定义类型时,我得到一个错误,即未定义与 row 中的字段关联的构造函数。这对于在row 中不匹配的任何header 是有意义的,将返回null 序列。一个例子:
mdrQuery |> Seq.head;;
val it :
seq<dbSchema.ServiceTypes.MDR_0916> * dbSchema.ServiceTypes.CustomerDetails
= (seq [null], CustomerDetails {ACCOUNTMANAGER = null;
ACCOUNTSTATUS = "XC";
ADDRESSLINE1 = null;
ADDRESSLINE2 = null;
ADDRESSLINE3 = null;
ADDRESSLINE4 = "123 PIG ROAD"...
由于the leftOuterJoin documentation here,我怀疑有办法解决这个问题。但是,当我尝试将该示例用作 my 查询的模板时:
let mdrQuery =
query {
for header in db.CustomerDetails do
leftOuterJoin row in db.MDR_0916
on (header.PID = row.PID) into result
for row in result.DefaultIfEmpty() do
select (result, header)
}
.DefaultIfEmpty() 用
error FS0039: The field, constructor or member 'DefaultIfEmpty' is not defined
有没有一种方法可以让这个连接发生并选择每一行,用None(或其他一些空 SQL 空值)填充 result 中不匹配的行,以便整个查询可以传递给我的记录类型吗?
理想情况下,不匹配行的输出类似于(以下手动创建的截断结果)
mdrQuery |> Seq.head;;
val it :
seq<dbSchema.ServiceTypes.MDR_0916> * dbSchema.ServiceTypes.CustomerDetails
= (MDR_0916 {AIMExp = null;
AP = null;
APComp = null;
APEng = null;
APFine = null;
APForl = null;...},
CustomerDetails {ACCOUNTMANAGER = null;
ACCOUNTSTATUS = "XC";
ADDRESSLINE1 = null;
ADDRESSLINE2 = null;
ADDRESSLINE3 = null;
ADDRESSLINE4 = "123 PIG ROAD"...
编辑: This question/answer 与我的相似,但包括 ToOption result 只会输出 Some (seq [null])。
【问题讨论】:
-
在你的交互式输出中,
result不是一个空序列,而是一个元素的序列,那个元素是null。 -
感谢您的澄清。
-
DefaultIfEmpty是扩展方法,所以需要open System.Linq。 -
打开
System.Linq会清除错误,但不会影响其他任何内容。
标签: f#