@@ -9,6 +9,9 @@ namespace Microsoft.EntityFrameworkCore.Query;
9
9
/// <inheritdoc />
10
10
public class SqlExpressionFactory : ISqlExpressionFactory
11
11
{
12
+ private static readonly bool UseOldBehavior35393 =
13
+ AppContext . TryGetSwitch ( "Microsoft.EntityFrameworkCore.Issue35393" , out var enabled35393 ) && enabled35393 ;
14
+
12
15
private readonly IRelationalTypeMappingSource _typeMappingSource ;
13
16
private readonly RelationalTypeMapping _boolTypeMapping ;
14
17
@@ -660,20 +663,45 @@ private SqlExpression Not(SqlExpression operand, SqlExpression? existingExpressi
660
663
SqlBinaryExpression { OperatorType : ExpressionType . OrElse } binary
661
664
=> AndAlso ( Not ( binary . Left ) , Not ( binary . Right ) ) ,
662
665
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
+ // more comprehensive optimization is done during null expansion
664
669
// !(a == true) -> a == false
665
670
// !(a == false) -> a == true
666
671
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
667
683
=> Equal ( binary . Left , Not ( binary . Right ) ) ,
668
684
669
685
// !(true == a) -> false == a
670
686
// !(false == a) -> true == a
671
687
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
672
699
=> Equal ( Not ( binary . Left ) , binary . Right ) ,
673
700
674
701
// !(a == b) -> a != b
675
702
SqlBinaryExpression { OperatorType : ExpressionType . Equal } sqlBinaryOperand => NotEqual (
676
703
sqlBinaryOperand . Left , sqlBinaryOperand . Right ) ,
704
+
677
705
// !(a != b) -> a == b
678
706
SqlBinaryExpression { OperatorType : ExpressionType . NotEqual } sqlBinaryOperand => Equal (
679
707
sqlBinaryOperand . Left , sqlBinaryOperand . Right ) ,
0 commit comments