I have a relatively simple F#
query expression with a join:
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)
}
This returns every header
and result
but for a header
that has not match in row
, result
is just an empty sequence and, when the query results are passed to a custom Type, I get an error that a constructor associated with a field in row
is not defined. This makes sense as for any header
that has no match in row
, a null
sequence is returned. An example:
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"...
I suspect that there's a way around this because of the leftOuterJoin
documentation here. But, when I try using that example as a template for my query:
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)
}
the .DefaultIfEmpty()
piece errors out with
error FS0039: The field, constructor or member 'DefaultIfEmpty' is not defined
Is there a way that I can make this join happen and select every row, filling the unmatched rows in result
with None
(or some other null SQL null value) so that the entirety of the query can be passed to my record type?
Ideally, the output for an unmatched row would be something like (truncated results created by hand below)
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"...
Edit: This question/answer is similar to mine but including ToOption result
simply outputs a Some (seq [null])
.