我有一个相对简单的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
,但对于header
中不匹配的row
,result
只是一个空序列,当查询结果传递给自定义类型,我得到一个错误,即没有定义与row
中的字段关联的构造函数。这对header
中没有匹配的任何row
都有意义,返回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
有没有办法让这个连接发生和选择每一行,用result
填充None
中不匹配的行(或其他一些空的SQL空值) )以便可以将整个查询传递给我的记录类型?
理想情况下,不匹配行的输出类似(下面手工创建的截断结果)
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])
。
答案 0 :(得分:0)
文档错了;在C#中,没有直接等效的leftOuterJoin
运算符,因此DefaultIfEmpty
与普通联接一起使用,但在F#中您不需要此(查询构建器为您执行此转换 - 请参阅{如果你很好奇,可以在source中{1}}。
如果您想要传统左连接的结果,那么只需添加额外的QueryBuilder.LeftOuterJoin
循环而不用 for
(但请注意 - 您要选择新绑定的{ {1}}值,不 DefaultIfEmpty
序列):
row
请注意,这会为缺少的result
条目提供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 do
select (row, header)
}
值,而不会为null
字段值提供特殊MDR_0916
值,因此您可能希望如果您需要后者,请应用后处理步骤。