Документация по leftOuterJoin
выражениям запросов в MSDN неоднократно подразумевает, что при используя leftOuterJoin .. on .. into ..
, вы все равно должны использовать .DefaultIfEmpty()
для достижения желаемого эффекта.
Я не считаю это необходимым, потому что я получаю одинаковые результаты в обоих этих тестах, которые отличаются только тем, что второй не .DefaultIfEpmty()
type Test = A | B | C
let G = [| A; B; C|]
let H = [| A; C; C|]
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.DefaultIfEmpty() do
select (g, i)}
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
select (g, i)}
// seq [(A, A); (B, null); (C, C); (C, C)]
// seq [(A, A); (B, null); (C, C); (C, C)]
1) Вы можете это подтвердить?
Если это так, то я понял это только после того, как написал эту альтернативную аугментацию типа в попытке лучше справиться с непревзойденными результатами, и я был удивлен, увидев все еще null
s в моем выводе!
type IEnumerable<'TSource> with
member this.NoneIfEmpty = if (Seq.exists (fun _ -> true) this)
then Seq.map (fun e -> Some e) this
else seq [ None ]
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.NoneIfEmpty do
select (g, i)}
// seq [(A, Some A); (B, Some null); (C, Some C); (C, Some C)]
2) Есть ли способ получить None
вместо null
/Some null
из leftOuterJoin
?
3) Что я действительно хочу сделать, так это выяснить, есть ли непревзойденные g
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I.NoneIfEmpty do
where (i.IsNone)
exists (true) }
Я понял следующее, но это не очень F #:
printfn "%A" <| query {
for g in G do
leftOuterJoin h in H on (g = h) into I
for i in I do
where (box i = null)
exists (true)}