-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Most databases can take advantage of indexes (and in some cases even auto-generate them) when queries perform equality comparisons (instead of inequality).
In some places EFCore already tries to lean towards equality
efcore/src/EFCore.Relational/Query/SqlExpressionFactory.cs
Lines 657 to 666 in 20edb63
| // use equality where possible | |
| // !(a == true) -> a == false | |
| // !(a == false) -> a == true | |
| SqlBinaryExpression { OperatorType: ExpressionType.Equal, Right: SqlConstantExpression { Value: bool } } binary | |
| => Equal(binary.Left, Not(binary.Right)), | |
| // !(true == a) -> false == a | |
| // !(false == a) -> true == a | |
| SqlBinaryExpression { OperatorType: ExpressionType.Equal, Left: SqlConstantExpression { Value: bool } } binary | |
| => Equal(Not(binary.Left), binary.Right), |
In other places it disregards this and in fact can even replace equality comparisons with inequalities
efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs
Lines 1748 to 1757 in 20edb63
| // a == b <=> !a == !b -> a == b | |
| // !a == b <=> a == !b -> a != b | |
| // a != b <=> !a != !b -> a != b | |
| // !a != b <=> a != !b -> a == b | |
| nullable = false; | |
| return sqlBinaryExpression.OperatorType == ExpressionType.Equal ^ leftNegated == rightNegated | |
| ? _sqlExpressionFactory.NotEqual(left, right) | |
| : _sqlExpressionFactory.Equal(left, right); |
efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs
Lines 1803 to 1804 in 20edb63
| // a == !b and !a == b in SQL evaluate the same as a != b | |
| body = _sqlExpressionFactory.NotEqual(left, right); |
It would be better to avoid converting equalities into inequalities and, when possible, convert inequalities into equalities.