var q = from a in A
join b in B on a.ID equals b.ID
join c in C on b.ID equals c.ID into G1
from g1 in G1.DefaultIfEmpty()
join d in D on b.ID equals d.ID into G2
from g2 in G2.DefaultIfEmpty()
select new { a, b, g1, g2 };
Only thing should be careful is that join condition must be
outer parameter equals inner parameter (b.ID equals c.ID)
It cannot be written as
inner parameter equals outer parameter ((c.ID equals b.ID))
That is little bit different from SQL join query.
join b in B on a.ID equals b.ID
join c in C on b.ID equals c.ID into G1
from g1 in G1.DefaultIfEmpty()
join d in D on b.ID equals d.ID into G2
from g2 in G2.DefaultIfEmpty()
select new { a, b, g1, g2 };
Only thing should be careful is that join condition must be
outer parameter equals inner parameter (b.ID equals c.ID)
It cannot be written as
inner parameter equals outer parameter ((c.ID equals b.ID))
That is little bit different from SQL join query.