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...
}