diff --git a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
index 636f5ed13dc..5ec0059b30c 100644
--- a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
@@ -143,6 +143,30 @@ private bool PreserveConvertNode(Expression expression)
return false;
}
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
+ {
+ var newTestExpression = TryGetConstantValue(conditionalExpression.Test) ?? Visit(conditionalExpression.Test);
+
+ if (newTestExpression is ConstantExpression constantTestExpression
+ && constantTestExpression.Value is bool constantTestValue)
+ {
+ return constantTestValue
+ ? Visit(conditionalExpression.IfTrue)
+ : Visit(conditionalExpression.IfFalse);
+ }
+
+ return conditionalExpression.Update(
+ newTestExpression,
+ Visit(conditionalExpression.IfTrue),
+ Visit(conditionalExpression.IfFalse));
+ }
+
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs
index 94c571c43b7..d8f55daf09e 100644
--- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs
@@ -824,6 +824,24 @@ public virtual Task Ternary_should_not_evaluate_both_sides(bool isAsync)
}));
}
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Ternary_should_not_evaluate_both_sides_with_parameter(bool isAsync)
+ {
+ DateTime? param = null;
+
+ return AssertQuery(
+ isAsync,
+ ss => ss.Set().Select(
+ o => new
+ {
+ // ReSharper disable SimplifyConditionalTernaryExpression
+ Data1 = param != null ? o.OrderDate == param.Value : true,
+ Data2 = param == null ? true : o.OrderDate == param.Value
+ // ReSharper restore SimplifyConditionalTernaryExpression
+ }));
+ }
+
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Null_Coalesce_Short_Circuit(bool isAsync)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
index 7c092752f8d..78926e176a7 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Where.cs
@@ -1450,6 +1450,15 @@ public override async Task Ternary_should_not_evaluate_both_sides(bool isAsync)
FROM [Customers] AS [c]");
}
+ public override async Task Ternary_should_not_evaluate_both_sides_with_parameter(bool isAsync)
+ {
+ await base.Ternary_should_not_evaluate_both_sides_with_parameter(isAsync);
+
+ AssertSql(
+ @"SELECT CAST(1 AS bit) AS [Data1]
+FROM [Orders] AS [o]");
+ }
+
public override async Task Where_compare_constructed_multi_value_equal(bool isAsync)
{
await base.Where_compare_constructed_multi_value_equal(isAsync);