Efcore: Nullable parameter in Select with ?: conditional operator throws InvalidOperationException

Created on 19 Sep 2019  路  4Comments  路  Source: dotnet/efcore

Description

If you use a nullable parameter in a select expression with ?: conditional operator, the EFCore provider evaulates the nullable object's value even that condition branch should be skipped.

Steps to reproduce

Consider this entity and query,

```C#
public class TestEntity
{
public int Id { get; set; }
public DateTime TestDateTime { get; set; }
}

public class TestDto
{
public bool Result { get; set; }
}

public class IndexModel : PageModel
{
private readonly ApplicationDbContext _context;

public IndexModel(ApplicationDbContext context)
{
    _context = context;
}

public async Task OnGet()
{
    var r1 = await ReproMethodAsync(DateTime.Now);
    var r2 = await ReproMethodAsync(null); // InvalidOperationException: Nullable object must have a value.
}

private async Task<List<TestDto>> ReproMethodAsync(DateTime? param)
{
    var results = await _context.Tests.Select(x => new TestDto
    {
        Result = param != null ? x.TestDateTime == param.Value : true,
    }).ToListAsync();

    return results;
}

}


#### StackTrace

InvalidOperationException: An exception was thrown while attempting to evaluate a LINQ query parameter expression. To show additional information call EnableSensitiveDataLogging() when overriding DbContext.OnConfiguring.
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.GetValue(Expression expression, out string parameterName)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Evaluate(Expression expression, bool generateParameter)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection nodes, Func elementVisitor)
System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Linq.Expressions.ExpressionVisitor.VisitLambda(Expression node)
System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.Visit(Expression expression)
Microsoft.EntityFrameworkCore.Query.Internal.ParameterExtractingExpressionVisitor.ExtractParameters(Expression expression)
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExtractParameters(Expression query, IParameterValues parameterValues, IDiagnosticsLogger logger, bool parameterize, bool generateContextAccessors)
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync(Expression query, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync(Expression expression, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable.GetAsyncEnumerator(CancellationToken cancellationToken)
System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable.GetAsyncEnumerator()
Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync(IQueryable source, CancellationToken cancellationToken)
```

Further technical details

EF Core version: 2.2, 3.0-rc1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET FW 4.x with 2.2, .NET Core 3.0-rc1
Operating system: WIndows 10 10.0.18362.356
IDE: Visual Studio 2019 16.3.0-preview4

closed-fixed customer-reported type-bug

Most helpful comment

@smitpatel @roji Confirmed fixed as of 3.1.0-preview3.19554.8 馃憤

All 4 comments

Related #13859

Will take a look at this.

Note: related to #12521 which was fixed for 2.2.0.

@smitpatel @roji Confirmed fixed as of 3.1.0-preview3.19554.8 馃憤

@fschlaef thanks for confirming!

Was this page helpful?
0 / 5 - 0 ratings