I have the following SQL, which I am trying to translate to LINQ:
SELECT f.value FROM period as p LEFT OUTER JOIN facts AS f ON p.id = f.periodid AND f.otherid = 17 WHERE p.companyid = 100
I have seen the typical implementation of the left outer join (ie. into x from y in x.DefaultIfEmpty()
etc.) but am unsure how to introduce the other join condition (AND f.otherid = 17
)
EDIT
Why is the AND f.otherid = 17
condition part of the JOIN instead of in the WHERE clause?
Because f
may not exist for some rows and I still want these rows to be included. If the condition is applied in the WHERE clause, after the JOIN – then I don’t get the behaviour I want.
Unfortunately this:
from p in context.Periods join f in context.Facts on p.id equals f.periodid into fg from fgi in fg.DefaultIfEmpty() where p.companyid == 100 && fgi.otherid == 17 select f.value
seems to be equivalent to this:
SELECT f.value FROM period as p LEFT OUTER JOIN facts AS f ON p.id = f.periodid WHERE p.companyid = 100 AND f.otherid = 17
which is not quite what I’m after.
Advertisement
Answer
You need to introduce your join condition before calling DefaultIfEmpty()
. I would just use extension method syntax:
from p in context.Periods join f in context.Facts on p.id equals f.periodid into fg from fgi in fg.Where(f => f.otherid == 17).DefaultIfEmpty() where p.companyid == 100 select f.value
Or you could use a subquery:
from p in context.Periods join f in context.Facts on p.id equals f.periodid into fg from fgi in (from f in fg where f.otherid == 17 select f).DefaultIfEmpty() where p.companyid == 100 select f.value