diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs index 458077cf47d..a8ee3eeb5a3 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs @@ -161,48 +161,45 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) return Visit(ConvertObjectArrayEqualityComparison(binaryExpression.Left, binaryExpression.Right)); } - if (!(AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled)) - { - if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual) - && (binaryExpression.Left.IsNullConstantExpression() || binaryExpression.Right.IsNullConstantExpression())) + if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual) + && (binaryExpression.Left.IsNullConstantExpression() || binaryExpression.Right.IsNullConstantExpression())) + { + var nonNullExpression = binaryExpression.Left.IsNullConstantExpression() ? binaryExpression.Right : binaryExpression.Left; + if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression + && nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable) + && nonNullMethodCallExpression.Method.IsGenericMethod + && SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition())) { - var nonNullExpression = binaryExpression.Left.IsNullConstantExpression() ? binaryExpression.Right : binaryExpression.Left; - if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression - && nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable) - && nonNullMethodCallExpression.Method.IsGenericMethod - && SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition())) + var source = nonNullMethodCallExpression.Arguments[0]; + if (nonNullMethodCallExpression.Arguments.Count == 2) { - var source = nonNullMethodCallExpression.Arguments[0]; - if (nonNullMethodCallExpression.Arguments.Count == 2) - { - source = Expression.Call( - QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()), - source, - nonNullMethodCallExpression.Arguments[1]); - } + source = Expression.Call( + QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()), + source, + nonNullMethodCallExpression.Arguments[1]); + } - var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source); - if (translatedSubquery != null) + var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source); + if (translatedSubquery != null) + { + var projection = translatedSubquery.ShaperExpression; + if (projection is NewExpression + || RemoveConvert(projection) is EntityShaperExpression { IsNullable: false }) { - var projection = translatedSubquery.ShaperExpression; - if (projection is NewExpression - || RemoveConvert(projection) is EntityShaperExpression { IsNullable: false }) - { - var anySubquery = Expression.Call( - QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()), - translatedSubquery); - - return Visit( - binaryExpression.NodeType == ExpressionType.Equal - ? Expression.Not(anySubquery) - : anySubquery); - } - - static Expression RemoveConvert(Expression e) - => e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary - ? RemoveConvert(unary.Operand) - : e; + var anySubquery = Expression.Call( + QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()), + translatedSubquery); + + return Visit( + binaryExpression.NodeType == ExpressionType.Equal + ? Expression.Not(anySubquery) + : anySubquery); } + + static Expression RemoveConvert(Expression e) + => e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary + ? RemoveConvert(unary.Operand) + : e; } } } diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs index 958ea235957..e310cee7d68 100644 --- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs @@ -302,48 +302,45 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) right = rightOperand!; } - if (!(AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled)) + if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual) + && (left.IsNullConstantExpression() || right.IsNullConstantExpression())) { - if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual) - && (left.IsNullConstantExpression() || right.IsNullConstantExpression())) + var nonNullExpression = left.IsNullConstantExpression() ? right : left; + if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression + && nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable) + && nonNullMethodCallExpression.Method.IsGenericMethod + && SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition())) { - var nonNullExpression = left.IsNullConstantExpression() ? right : left; - if (nonNullExpression is MethodCallExpression nonNullMethodCallExpression - && nonNullMethodCallExpression.Method.DeclaringType == typeof(Queryable) - && nonNullMethodCallExpression.Method.IsGenericMethod - && SingleResultMethodInfos.Contains(nonNullMethodCallExpression.Method.GetGenericMethodDefinition())) + var source = nonNullMethodCallExpression.Arguments[0]; + if (nonNullMethodCallExpression.Arguments.Count == 2) { - var source = nonNullMethodCallExpression.Arguments[0]; - if (nonNullMethodCallExpression.Arguments.Count == 2) - { - source = Expression.Call( - QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()), - source, - nonNullMethodCallExpression.Arguments[1]); - } + source = Expression.Call( + QueryableMethods.Where.MakeGenericMethod(source.Type.GetSequenceType()), + source, + nonNullMethodCallExpression.Arguments[1]); + } - var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source); - if (translatedSubquery != null) + var translatedSubquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(source); + if (translatedSubquery != null) + { + var projection = translatedSubquery.ShaperExpression; + if (projection is NewExpression + || RemoveConvert(projection) is EntityShaperExpression { IsNullable: false }) { - var projection = translatedSubquery.ShaperExpression; - if (projection is NewExpression - || RemoveConvert(projection) is EntityShaperExpression { IsNullable: false }) - { - var anySubquery = Expression.Call( - QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()), - translatedSubquery); - - return Visit( - binaryExpression.NodeType == ExpressionType.Equal - ? Expression.Not(anySubquery) - : anySubquery); - } - - static Expression RemoveConvert(Expression e) - => e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary - ? RemoveConvert(unary.Operand) - : e; + var anySubquery = Expression.Call( + QueryableMethods.AnyWithoutPredicate.MakeGenericMethod(translatedSubquery.Type.GetSequenceType()), + translatedSubquery); + + return Visit( + binaryExpression.NodeType == ExpressionType.Equal + ? Expression.Not(anySubquery) + : anySubquery); } + + static Expression RemoveConvert(Expression e) + => e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary + ? RemoveConvert(unary.Operand) + : e; } } } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index 2ccc6dd819b..531b5ea81bd 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -2205,23 +2205,16 @@ private void AddJoin( return; } - if (!AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue27072", out var enabled27072) || !enabled27072) + if (originalInnerSelectPredicate != null) { - if (originalInnerSelectPredicate != null) + if (innerSelectExpression.GroupBy.Count > 0) { - if (innerSelectExpression.GroupBy.Count > 0) - { - innerSelectExpression.Having = originalInnerSelectPredicate; - } - else - { - innerSelectExpression.Predicate = originalInnerSelectPredicate; - } + innerSelectExpression.Having = originalInnerSelectPredicate; + } + else + { + innerSelectExpression.Predicate = originalInnerSelectPredicate; } - } - else - { - innerSelectExpression.ApplyPredicate(joinPredicate); } joinPredicate = null; @@ -2484,49 +2477,19 @@ static void GetPartitions(SelectExpression selectExpression, SqlExpression sqlEx static bool IsContainedSql(SelectExpression selectExpression, SqlExpression sqlExpression) { - if (!AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26756", out var enabled) || !enabled) - { - switch (sqlExpression) - { - case ColumnExpression columnExpression: - return selectExpression.ContainsTableReference(columnExpression); - - case CaseExpression caseExpression - when caseExpression.ElseResult == null - && caseExpression.Operand == null - && caseExpression.WhenClauses.Count == 1 - && caseExpression.WhenClauses[0].Result is ColumnExpression resultColumn: - // We check condition in a separate function to avoid matching structure of condition outside of case block - return IsContainedCondition(selectExpression, caseExpression.WhenClauses[0].Test) - && selectExpression.ContainsTableReference(resultColumn); - - default: - return false; - } - } - switch (sqlExpression) { case ColumnExpression columnExpression: return selectExpression.ContainsTableReference(columnExpression); - case SqlConstantExpression sqlConstantExpression - when sqlConstantExpression.Value == null: - return true; - - case SqlBinaryExpression sqlBinaryExpression - when sqlBinaryExpression.OperatorType == ExpressionType.AndAlso - || sqlBinaryExpression.OperatorType == ExpressionType.OrElse - || sqlBinaryExpression.OperatorType == ExpressionType.NotEqual: - return IsContainedSql(selectExpression, sqlBinaryExpression.Left) - && IsContainedSql(selectExpression, sqlBinaryExpression.Right); - case CaseExpression caseExpression when caseExpression.ElseResult == null && caseExpression.Operand == null - && caseExpression.WhenClauses.Count == 1: - return IsContainedSql(selectExpression, caseExpression.WhenClauses[0].Test) - && IsContainedSql(selectExpression, caseExpression.WhenClauses[0].Result); + && caseExpression.WhenClauses.Count == 1 + && caseExpression.WhenClauses[0].Result is ColumnExpression resultColumn: + // We check condition in a separate function to avoid matching structure of condition outside of case block + return IsContainedCondition(selectExpression, caseExpression.WhenClauses[0].Test) + && selectExpression.ContainsTableReference(resultColumn); default: return false; diff --git a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs index e29f97973f3..ace1bc5342b 100644 --- a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs @@ -71,37 +71,6 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) } } - if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue26744", out var enabled) && enabled) - { - if (binaryExpression.NodeType == ExpressionType.Equal - || binaryExpression.NodeType == ExpressionType.NotEqual) - { - var leftNullConstant = IsNullConstant(left); - var rightNullConstant = IsNullConstant(right); - if (leftNullConstant || rightNullConstant) - { - var nonNullExpression = leftNullConstant ? right : left; - if (nonNullExpression is MethodCallExpression methodCallExpression - && methodCallExpression.Method.DeclaringType == typeof(Queryable) - && methodCallExpression.Method.IsGenericMethod - && methodCallExpression.Method.GetGenericMethodDefinition() is MethodInfo genericMethod - && SingleResultMethodInfos.Contains(genericMethod)) - { - var result = Expression.Call( - (methodCallExpression.Arguments.Count == 2 - ? QueryableMethods.AnyWithPredicate - : QueryableMethods.AnyWithoutPredicate) - .MakeGenericMethod(methodCallExpression.Type), - methodCallExpression.Arguments); - - return binaryExpression.NodeType == ExpressionType.Equal - ? Expression.Not(result) - : result; - } - } - } - } - return binaryExpression.Update(left, binaryExpression.Conversion, right); }