Search code examples
c#postgresqllinqdevart

LINQ left join generates wrong SQL query


I have this LINQ query:

from sol in context.SalesOrderLines
join mpso in context.MulticlientsoParentChildsoRelations on sol.orderid equals mpso.parentsalesorderid into lmpso
from mpso in lmpso.DefaultIfEmpty()
join cso in context.SalesOrders on mpso.childsalesorderid equals cso.id into lcso
from cso in lcso.DefaultIfEmpty()
join csol in context.SalesOrderLines on cso.id equals csol.orderid into lcsol
from csol in lcsol.DefaultIfEmpty()
join pll in context.PickingLine on (csol == null ? sol.id : csol.id) equals pll.salesorderlineid
join pl in context.PickingLists on pll.pickinglistid equals pl.id
join pfi in context.PfiSubmitterQuantities on pll.id equals pfi.pickinglineid into ppfi
from pfi in ppfi.DefaultIfEmpty()
where sol.orderid == palletid && (pfi == null ? pl.wholepallets == true : true)
select new Helper { Id = pfi.palletid ?? pll.palletid, BoolValue01 = pfi == null } 

And here is sixth line with left join

join csol in context.SalesOrderLines on cso.id equals csol.orderid into lcsol
from csol in lcsol.DefaultIfEmpty()

And it generates strange SQL query, here's how it looks when I do linq to sql (take a look at 7th line):

SELECT distinct
  CASE  WHEN (pfi."palletid" IS NULL) THEN (pll."palletid") ELSE (pfi."palletid") END  AS "C1",
  CASE  WHEN (pfi."id" IS NULL) THEN (TRUE) ELSE (FALSE) END  AS "C2"
FROM salesorderlines AS sol
  LEFT OUTER JOIN multiclientso_parentchildsorelations AS mpso ON sol."orderid" = mpso."parentsalesorderid"
  LEFT OUTER JOIN salesorders AS cso ON mpso."childsalesorderid" = cso."id"
  LEFT OUTER JOIN salesorderlines AS csol ON cso."id" = csol."orderid" OR cso."id" IS NULL AND csol."orderid" IS NULL
  INNER JOIN pickingline AS pll ON
    CASE WHEN (csol."id" IS NOT NULL) THEN (csol."id") ELSE (sol."id") END  = pll."salesorderlineid"
    OR CASE WHEN (csol."id" IS NOT NULL) THEN (csol."id") ELSE (sol."id") END IS NULL AND pll."salesorderlineid" IS NULL
  INNER JOIN pickinglist AS pl ON pll."pickinglistid" = pl."id"
  LEFT OUTER JOIN pfi_submittedquantities AS pfi ON pll."id" = pfi."pickinglineid"
WHERE sol."orderid" = 24863039
  AND  CASE  WHEN (pfi."id" IS NULL) THEN ( CASE  WHEN (TRUE = pl."wholepallets") THEN (TRUE) WHEN (NOT (TRUE = pl."wholepallets" AND pl."wholepallets" IS NOT NULL)) THEN (FALSE) END ) ELSE (TRUE) END  = TRUE

The problem is how does my linq left join translates from this LINQ

join csol in context.SalesOrderLines on cso.id equals csol.orderid into lcsol
from csol in lcsol.DefaultIfEmpty()

to this SQL

LEFT OUTER JOIN salesorderlines AS csol ON cso."id" = csol."orderid" OR cso."id" IS NULL AND csol."orderid" IS NULL

From where does the OR part comes?


Solution

  • Thanks to @ArcaArtem, I've found that SalesOrderLines table had orderid nullable int foreign key field, which in my case would never be null, so changed it to simple int. Now it generates correct sql.