@@ -32,7 +32,7 @@ public class SearchConditionConverter(ISqlExpressionFactory sqlExpressionFactory
3232    /// </summary> 
3333    [ return :  NotNullIfNotNull ( nameof ( expression ) ) ] 
3434    public  override  Expression ?  Visit ( Expression ?  expression ) 
35-         =>  Visit ( expression ,  inSearchConditionContext :  false ) ; 
35+         =>  Visit ( expression ,  inSearchConditionContext :  false ,   allowNullFalseEquivalence :   false ) ; 
3636
3737    /// <summary> 
3838    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to 
@@ -41,12 +41,12 @@ public class SearchConditionConverter(ISqlExpressionFactory sqlExpressionFactory
4141    ///     doing so can result in application failures when updating to a new Entity Framework Core release. 
4242    /// </summary> 
4343    [ return :  NotNullIfNotNull ( nameof ( expression ) ) ] 
44-     protected  virtual  Expression ?  Visit ( Expression ?  expression ,  bool  inSearchConditionContext ) 
44+     protected  virtual  Expression ?  Visit ( Expression ?  expression ,  bool  inSearchConditionContext ,   bool   allowNullFalseEquivalence ) 
4545        =>  expression  switch 
4646        { 
47-             CaseExpression  e  =>  VisitCase ( e ,  inSearchConditionContext ) , 
47+             CaseExpression  e  =>  VisitCase ( e ,  inSearchConditionContext ,   allowNullFalseEquivalence ) , 
4848            SelectExpression  e  =>  VisitSelect ( e ) , 
49-             SqlBinaryExpression  e  =>  VisitSqlBinary ( e ,  inSearchConditionContext ) , 
49+             SqlBinaryExpression  e  =>  VisitSqlBinary ( e ,  inSearchConditionContext ,   allowNullFalseEquivalence ) , 
5050            SqlUnaryExpression  e  =>  VisitSqlUnary ( e ,  inSearchConditionContext ) , 
5151            PredicateJoinExpressionBase  e  =>  VisitPredicateJoin ( e ) , 
5252
@@ -139,19 +139,19 @@ private SqlExpression SimplifyNegatedBinary(SqlExpression sqlExpression)
139139    ///     any release. You should only use it directly in your code with extreme caution and knowing that 
140140    ///     doing so can result in application failures when updating to a new Entity Framework Core release. 
141141    /// </summary> 
142-     protected  virtual  Expression  VisitCase ( CaseExpression  caseExpression ,  bool  inSearchConditionContext ) 
142+     protected  virtual  Expression  VisitCase ( CaseExpression  caseExpression ,  bool  inSearchConditionContext ,   bool   allowNullFalseEquivalence ) 
143143    { 
144144        var  testIsCondition  =  caseExpression . Operand  is  null ; 
145145        var  operand  =  ( SqlExpression ? ) Visit ( caseExpression . Operand ) ; 
146146        var  whenClauses  =  new  List < CaseWhenClause > ( ) ; 
147147        foreach  ( var  whenClause  in  caseExpression . WhenClauses ) 
148148        { 
149-             var  test  =  ( SqlExpression ) Visit ( whenClause . Test ,  testIsCondition ) ; 
150-             var  result  =  ( SqlExpression ) Visit ( whenClause . Result ) ; 
149+             var  test  =  ( SqlExpression ) Visit ( whenClause . Test ,  testIsCondition ,   testIsCondition ) ; 
150+             var  result  =  ( SqlExpression ) Visit ( whenClause . Result ,   inSearchConditionContext :   false ,   allowNullFalseEquivalence ) ; 
151151            whenClauses . Add ( new  CaseWhenClause ( test ,  result ) ) ; 
152152        } 
153153
154-         var  elseResult  =  ( SqlExpression ? ) Visit ( caseExpression . ElseResult ) ; 
154+         var  elseResult  =  ( SqlExpression ? ) Visit ( caseExpression . ElseResult ,   inSearchConditionContext :   false ,   allowNullFalseEquivalence ) ; 
155155
156156        return  ApplyConversion ( 
157157            sqlExpressionFactory . Case ( operand ,  whenClauses ,  elseResult ,  caseExpression ) , 
@@ -168,7 +168,7 @@ protected virtual Expression VisitCase(CaseExpression caseExpression, bool inSea
168168    protected  virtual  Expression  VisitPredicateJoin ( PredicateJoinExpressionBase  join ) 
169169        =>  join . Update ( 
170170            ( TableExpressionBase ) Visit ( join . Table ) , 
171-             ( SqlExpression ) Visit ( join . JoinPredicate ,  inSearchConditionContext :  true ) ) ; 
171+             ( SqlExpression ) Visit ( join . JoinPredicate ,  inSearchConditionContext :  true ,   allowNullFalseEquivalence :   true ) ) ; 
172172
173173    /// <summary> 
174174    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to 
@@ -179,9 +179,9 @@ protected virtual Expression VisitPredicateJoin(PredicateJoinExpressionBase join
179179    protected  virtual  Expression  VisitSelect ( SelectExpression  select ) 
180180    { 
181181        var  tables  =  this . VisitAndConvert ( select . Tables ) ; 
182-         var  predicate  =  ( SqlExpression ? ) Visit ( select . Predicate ,  inSearchConditionContext :  true ) ; 
182+         var  predicate  =  ( SqlExpression ? ) Visit ( select . Predicate ,  inSearchConditionContext :  true ,   allowNullFalseEquivalence :   true ) ; 
183183        var  groupBy  =  this . VisitAndConvert ( select . GroupBy ) ; 
184-         var  havingExpression  =  ( SqlExpression ? ) Visit ( select . Having ,  inSearchConditionContext :  true ) ; 
184+         var  havingExpression  =  ( SqlExpression ? ) Visit ( select . Having ,  inSearchConditionContext :  true ,   allowNullFalseEquivalence :   true ) ; 
185185        var  projections  =  this . VisitAndConvert ( select . Projection ) ; 
186186        var  orderings  =  this . VisitAndConvert ( select . Orderings ) ; 
187187        var  offset  =  ( SqlExpression ? ) Visit ( select . Offset ) ; 
@@ -196,19 +196,19 @@ protected virtual Expression VisitSelect(SelectExpression select)
196196    ///     any release. You should only use it directly in your code with extreme caution and knowing that 
197197    ///     doing so can result in application failures when updating to a new Entity Framework Core release. 
198198    /// </summary> 
199-     protected  virtual  Expression  VisitSqlBinary ( SqlBinaryExpression  binary ,  bool  inSearchConditionContext ) 
199+     protected  virtual  Expression  VisitSqlBinary ( SqlBinaryExpression  binary ,  bool  inSearchConditionContext ,   bool   allowNullFalseEquivalence ) 
200200    { 
201201        // Only logical operations need conditions on both sides 
202202        var  areOperandsInSearchConditionContext  =  binary . OperatorType  is  ExpressionType . AndAlso  or ExpressionType . OrElse ; 
203203
204-         var  newLeft  =  ( SqlExpression ) Visit ( binary . Left ,  areOperandsInSearchConditionContext ) ; 
205-         var  newRight  =  ( SqlExpression ) Visit ( binary . Right ,  areOperandsInSearchConditionContext ) ; 
204+         var  newLeft  =  ( SqlExpression ) Visit ( binary . Left ,  areOperandsInSearchConditionContext ,   allowNullFalseEquivalence :   false ) ; 
205+         var  newRight  =  ( SqlExpression ) Visit ( binary . Right ,  areOperandsInSearchConditionContext ,   allowNullFalseEquivalence :   false ) ; 
206206
207207        if  ( binary . OperatorType  is  ExpressionType . NotEqual  or ExpressionType . Equal ) 
208208        { 
209209            var  leftType  =  newLeft . TypeMapping ? . Converter ? . ProviderClrType  ??  newLeft . Type ; 
210210            var  rightType  =  newRight . TypeMapping ? . Converter ? . ProviderClrType  ??  newRight . Type ; 
211-             if  ( ! inSearchConditionContext 
211+             if  ( ! inSearchConditionContext   &&   ! allowNullFalseEquivalence 
212212                &&  ( leftType  ==  typeof ( bool )  ||  leftType . IsInteger ( ) ) 
213213                &&  ( rightType  ==  typeof ( bool )  ||  rightType . IsInteger ( ) ) ) 
214214            { 
@@ -309,7 +309,7 @@ protected virtual Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression
309309                        sqlUnaryExpression . OperatorType ,  typeof ( SqlUnaryExpression ) ) ) ; 
310310        } 
311311
312-         var  operand  =  ( SqlExpression ) Visit ( sqlUnaryExpression . Operand ,  isOperandInSearchConditionContext ) ; 
312+         var  operand  =  ( SqlExpression ) Visit ( sqlUnaryExpression . Operand ,  isOperandInSearchConditionContext ,   allowNullFalseEquivalence :   false ) ; 
313313
314314        return  SimplifyNegatedBinary ( 
315315            ApplyConversion ( 
0 commit comments