Skip to content

Commit

Permalink
Fix conditional expression evaluation in ParameterExtractingEV
Browse files Browse the repository at this point in the history
Fixes #17942
  • Loading branch information
roji committed Oct 29, 2019
1 parent 45adf14 commit 7cdf25b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,30 @@ private bool PreserveConvertNode(Expression expression)
return false;
}

/// <summary>
/// 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.
/// </summary>
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));
}

/// <summary>
/// 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
Expand Down
18 changes: 18 additions & 0 deletions test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Order>().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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7cdf25b

Please sign in to comment.