Skip to content

Select Issue in EFCore 3 Update #385

@andresgbertola

Description

@andresgbertola

After updating from EFCore 2.1 to EFCore 3.0 I started getting an error when using a select clause in System.Dynamic.Linq.

I have for example these three entity classes:

An Order has a Customer, and a Customer has a collection of DeliveryPoints.

namespace Domain
{
    using System;
    using System.Collections.Generic;

    public class Order
    {
        public long Id { get; set; }
        public Customer Customer { get; set; }
	public long CustomerId { get; set; }
    }

    public class Customer
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public ICollection<DeliveryPoint> DeliveryPoints { get; set; }
	public ICollection<Order> Orders { get; set; }
    }

    public class DeliveryPoint
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
	public Customer Customer { get; set; }
	public long CustomerId { get; set; }
    }
}

Each class has more properties, but I will just keep it simple for the example.
Then. I have a code generator method to dinamically generate the "select" string to be executed using System.Dynamic.Linq.

// Dynamically created selectStatement base on querystring parameters:
var selectStatement = "new (Id, Customer == null ? null : new (Customer.Id, Customer.Name, Customer.DeliveryPoints.Select(new (Id, Name, Address)).ToArray() as DeliveryPoints) as Customer)";
                
// Filters the order DbSet with Id = 12 and selects the requested properties using dynamic linq.
var orderQuery = dbContext.Orders.Where(x => x.Id == 12).Select(selectStatement) as IQueryable<object>();

// Executes the query.
var order = await orderQuery.SingleOrDefault();

As I said, this is working in EF Core 2.1, but not with EF Core 3.0.

Now I´m getting this error when the SingleOrDefault(); is performed in the last sentence:

{"Value cannot be null. (Parameter 'bindings')"}

The problem seems to be in this kind of statement:

new (Customer.Id, Customer.Name, Customer.DeliveryPoints.Select(new (Id, Name, Address)).ToArray() as DeliveryPoints) as Customer)
Where it creates one object with an array inside. In this case, a Customer, with a DeliveryPoints Array.

Stacktrace:

   at System.Linq.Expressions.Expression.ValidateMemberInitArgs(Type type, ReadOnlyCollection`1 bindings)
   at System.Linq.Expressions.Expression.MemberInit(NewExpression newExpression, IEnumerable`1 bindings)
   at System.Linq.Expressions.MemberInitExpression.Update(NewExpression newExpression, IEnumerable`1 bindings)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitConditional(ConditionalExpression conditionalExpression)
   at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Translate(InMemoryQueryExpression queryExpression, Expression expression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.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 XRest.EntityFrameworkCore.EntityFrameworkCoreExtensions.<GetSelectiveAsync>d__5`1.MoveNext() in C:\Git\XRest\EntityFrameworkCore\EntityFrameworkCoreExtensions.cs:line 111

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions