This question is locked. New answers and comments are not allowed.
Using mssql when casting a bool field to bool? in where expressions 'field <> 0' is generated which is a conditional expression and not a nullable bit field. This is especially annoying when the field comes from a left-joined table and I need to treat it as nullable. E.g.
from a
in
db.Table1
join b
in
db.Table2 on ... equals ... into bg
from b
in
bg.DefaultIfEmpty()
join c
in
db.Table3 on ... equals ... into cg
from c
in
cg.DefaultIfEmpty()
where (
bool
?)b.Flag ?? (
bool
?)c.Flag ??
false
select a
generates ISNULL(b.[Flag] <> 0,ISNULL(c.[Flag] <> 0,(1=0))). This works properly for Nullable<int>, but not for bool. The ORM should always ignore the cast from T to Nullable<T> when generating the query.
If I write (b ?? c).Allow the generated code is ISNULL(b.[Flag], c.[ID]) -- didn't ever get the column right! -- which is not a conditional expression, syntax error again.
Also note the constant 'false' is translated to (1=0) and 'true' to (1=1) so if I use ((bool?)b.Flag ?? (bool?)c.Flag) == true the generated code is ISNULL(b.[Flag]<>0, c.[Flag]<>0)=(1=1) which is again malformed.
You should only create a predicate expression from a bit expression when required (e.g. when combining with logical operators), the pattern would be "(case when [expression]=1 then 1 else 0 end)=1" or "isnull([expression], 0)=1"
A possible workaround is this: ((b ?? c) != null ? (b ?? c).Allow : false) or (b != null ? b.Allow : c.Allow), the latter generates quite complicated code if the PK is long.