Mam stosunkowo prostą F#
wyrażenie kwerendy z sprzężenia:leftOuterJoin i `.DefaultIfEmpty()` zapytań w 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)
}
ta zwraca każdy header
i result
ale dla header
że nie pasuje w row
, result
jest po prostu pustą sekwencją, a gdy wyniki zapytania zostaną przekazane do niestandardowego typu, pojawia się błąd, że konstruktor powiązany z polem w row
nie jest zdefiniowany. Ma to sens, podobnie jak w przypadku każdego header
, który nie ma odpowiednika w row
, zwracana jest sekwencja . Przykład:
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"...
Podejrzewam, że istnieje sposób obejścia tego powodu the leftOuterJoin
documentation here. Ale gdy próbuję przy użyciu tego przykładu jako szablon do moim zapytania:
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)
}
się .DefaultIfEmpty()
kawałek błędów zewnątrz z
error FS0039: The field, constructor or member 'DefaultIfEmpty' is not defined
Czy istnieje sposób, że mogę zrobić to przyłączyć się zdarzyć i wybierz każdy wiersz, wypełniając niedopasowane wiersze w result
za pomocą None
(lub jakiejś innej pustej wartości zerowej SQL), aby całość zapytania mogła zostać przekazana do mojego typu rekordu?
Idealnie, wyjście na niezrównaną rzędu byłoby coś jak (skrócony wyników tworzonych ręcznie poniżej)
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 jest podobny do kopalni, ale w tym ToOption result
prostu wyprowadza Some (seq [null])
.
W twoim interaktywnym wyjściu 'wynik' nie jest pustą sekwencją, ale raczej sekwencją jednego elementu, a ten element to' null'. –
Dzięki za wyjaśnienia. – Steven
'DefaultIfEmpty' jest metodą rozszerzenia, więc musisz' otworzyć System.Linq'. – kvb