@@ -9,6 +9,9 @@ namespace Microsoft.EntityFrameworkCore.Query;
99/// <inheritdoc />
1010public class SqlExpressionFactory : ISqlExpressionFactory
1111{
12+ private static readonly bool UseOldBehavior35393 =
13+ AppContext . TryGetSwitch ( "Microsoft.EntityFrameworkCore.Issue35393" , out var enabled35393 ) && enabled35393 ;
14+
1215 private readonly IRelationalTypeMappingSource _typeMappingSource ;
1316 private readonly RelationalTypeMapping _boolTypeMapping ;
1417
@@ -660,20 +663,45 @@ private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpressi
660663 SqlBinaryExpression { OperatorType : ExpressionType . OrElse } binary
661664 => AndAlso ( Not ( binary . Left ) , Not ( binary . Right ) ) ,
662665
663- // use equality where possible
666+ // use equality where possible - we can only do this when we know a is not null
667+ // at this point we are limited to constants, parameters and columns
668+ // see issue #35393
664669 // !(a == true) -> a == false
665670 // !(a == false) -> a == true
666671 SqlBinaryExpression { OperatorType : ExpressionType . Equal , Right : SqlConstantExpression { Value : bool } } binary
672+ when UseOldBehavior35393
673+ => Equal ( binary . Left , Not ( binary . Right ) ) ,
674+
675+ SqlBinaryExpression
676+ {
677+ OperatorType : ExpressionType . Equal ,
678+ Right : SqlConstantExpression { Value : bool } ,
679+ Left : SqlConstantExpression { Value : bool }
680+ or SqlParameterExpression { IsNullable : false }
681+ or ColumnExpression { IsNullable : false }
682+ } binary
667683 => Equal ( binary . Left , Not ( binary . Right ) ) ,
668684
669685 // !(true == a) -> false == a
670686 // !(false == a) -> true == a
671687 SqlBinaryExpression { OperatorType : ExpressionType . Equal , Left : SqlConstantExpression { Value : bool } } binary
688+ when UseOldBehavior35393
689+ => Equal ( Not ( binary . Left ) , binary . Right ) ,
690+
691+ SqlBinaryExpression
692+ {
693+ OperatorType : ExpressionType . Equal ,
694+ Left : SqlConstantExpression { Value : bool } ,
695+ Right : SqlConstantExpression { Value : bool }
696+ or SqlParameterExpression { IsNullable : false }
697+ or ColumnExpression { IsNullable : false }
698+ } binary
672699 => Equal ( Not ( binary . Left ) , binary . Right ) ,
673700
674701 // !(a == b) -> a != b
675702 SqlBinaryExpression { OperatorType : ExpressionType . Equal } sqlBinaryOperand => NotEqual (
676703 sqlBinaryOperand . Left , sqlBinaryOperand . Right ) ,
704+
677705 // !(a != b) -> a == b
678706 SqlBinaryExpression { OperatorType : ExpressionType . NotEqual } sqlBinaryOperand => Equal (
679707 sqlBinaryOperand . Left , sqlBinaryOperand . Right ) ,
0 commit comments