Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullReferenceException when translating nested SelectMany with Constructor calls #19247

Closed
JakenVeina opened this issue Dec 9, 2019 · 3 comments
Assignees
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Milestone

Comments

@JakenVeina
Copy link

JakenVeina commented Dec 9, 2019

I'm getting a reproducible NullReferenceException when translating the following query...

var results3 = await context.Set<MyParentVersionEntity>()
    .Where(pv => pv.NextVersionId == null)
    .Select(pv => new MyParentDetailViewModel(
        pv.ParentId,
        pv.Name,
        pv.Parent.Children
            .SelectMany(c => c.Versions
                .Where(cv => cv.NextVersionId == null)
                .Where(cv => !cv.IsDeleted)
                .Select(cv => new MyChildIdentityViewModel(
                    cv.ChildId,
                    cv.Name)))
            .ToArray()))
    .ToArrayAsync();

The query runs correctly with either of the following tweaks:

Un-nesting the subquery within .SelectMany()

var results2 = await context.Set<MyParentVersionEntity>()
    .Where(pv => pv.NextVersionId == null)
    .Select(pv => new MyParentDetailViewModel(
        pv.ParentId,
        pv.Name,
        pv.Parent.Children
            .SelectMany(c => c.Versions)
            .Where(cv => cv.NextVersionId == null)
            .Where(cv => !cv.IsDeleted)
            .Select(cv => new MyChildIdentityViewModel(
                cv.ChildId,
                cv.Name))
            .ToArray()))
    .ToArrayAsync();

Replacing the constructor calls with anonymous objects

var results1 = await context.Set<MyParentVersionEntity>()
    .Where(pv => pv.NextVersionId == null)
    .Select(pv => new
    {
        pv.ParentId,
        pv.Name,
        Children = pv.Parent.Children
            .SelectMany(c => c.Versions
                .Where(cv => cv.NextVersionId == null)
                .Where(cv => !cv.IsDeleted)
                .Select(cv => new
                {
                    cv.ChildId,
                    cv.Name
                }))
            .ToArray()
    })
    .ToArrayAsync();

Full reproduction test case: https://github.com/JakenVeina/EFCoreSelectManyTest.

Stack Trace:

   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.MemberAccessShiftingExpressionVisitor.VisitExtension(Expression node)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitNew(NewExpression node)
   at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.CombineShapers(Expression queryExpression, Expression outerShaper, Expression innerShaper, Type transparentIdentifierType)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateResultSelectorForJoin(ShapedQueryExpression outer, LambdaExpression resultSelector, Expression innerShaper, Type transparentIdentifierType)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelectMany(ShapedQueryExpression source, LambdaExpression collectionSelector, LambdaExpression resultSelector)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCall)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal.NpgsqlSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCall)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
   at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToListAsync>d__64`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToArrayAsync>d__65`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at EFCoreSelectManyTest.Program.<Main>d__0.MoveNext() in D:\Projects\EFCoreSelectManyTest\Program.cs:line 61

EF Core version: 3.1.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: .NET Core 3.0
Operating system: Windows 8.1 Pro
IDE: Visual Studio Community 2019 16.4.0

@ghost
Copy link

ghost commented Mar 11, 2020

It's still an issue in EF Core 3.1.2 for SQL Server.

@smitpatel
Copy link
Contributor

This happens when TranslateResultSelectorForJoin runs through a client eval projection.

@smitpatel
Copy link
Contributor

Poaching. Need this for #20892

@smitpatel smitpatel added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed consider-for-current-release punted-for-5.0 labels Jun 10, 2020
@smitpatel smitpatel modified the milestones: Backlog, 5.0.0 Jun 10, 2020
smitpatel added a commit that referenced this issue Jun 10, 2020
smitpatel added a commit that referenced this issue Jun 10, 2020
smitpatel added a commit that referenced this issue Jun 10, 2020
smitpatel added a commit that referenced this issue Jun 10, 2020
smitpatel added a commit that referenced this issue Jun 12, 2020
Extension of #19247 for collection shaper in client eval
smitpatel added a commit that referenced this issue Jun 12, 2020
Extension of #19247 for collection shaper in client eval
smitpatel added a commit that referenced this issue Jun 12, 2020
Extension of #19247 for collection shaper in client eval
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-preview7 Jun 22, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-preview7, 5.0.0 Nov 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

No branches or pull requests

4 participants