Let's say I have 3 tables - 1 header and 2 detail:
Header Table
id | label
 1 | foo
 2 | bar
Detail 1 Table
id | date       | value
 1 | 2015-01-01 |     5
Detail 2 Table
id | date       | value
 1 | 2015-01-01 |     7
 2 | 2016-02-02 |    10
I want to make a linq query that joins all three, but does not eliminate data due to one detail table not having a record where the other one does. The result should look like:
Resulting Table
id | label | date       | value1 | value2
 1 | foo   | 2015-01-01 |      5 |      7
 2 | bar   | 2016-02-02 | <null> |     10
So, a null for value1, instead of the entire row being removed.
If I were writing SQL, I could write
select
    h.id,
    h.label,
    coalesce(d1.date, d2.date) as date,
    d1.value as value1,
    d2.value as value2
from
    header h
    left join detail1 d1
        on d1.id = h.id
    left join detail2 d2
        on d2.id = h.id
        and (
            d2.date = d1.date
            or d1.date is null
        )
Is it possible to write this using Linq? I'm using the "on new equals new " syntax, and I cannot figure out how to preserve the detail2 record when there is no matching detail1 record.
Edit: I feel like the linked answer only answers the left join portion of my question. I know I can left join in linq, but the detail2 table is joining on to both header (not a problem) and detail1. If detail1 doesn't have a record for a date in detail2, the detail2 record will not appear in the result. Using "select new{} equals new{}" doesn't allow me to use the detail2 object before the equals, so I can't write
from
    h in header.AsEnumerable()
join d1.AsEnumerable().DefaultIfEmpty()
    on p.Id equals d1.Id
join d2.AsEnumerable().DefaultIfEmpty()
    on new {
        Id = h["Id"],
        Date = d1["Date"] ?? d2["Date"], // Doesn't work, can't use d2 here.
    }                                    // d1 may not have a record, so there may not be a match
    equals new {
        Id = d2["Id"],
        Date = d2["Date"],
    }
select new {
    // etc...
}