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

Select Issue in EFCore 3 Update #385

Closed
andresgbertola opened this issue Jun 6, 2020 · 3 comments
Closed

Select Issue in EFCore 3 Update #385

andresgbertola opened this issue Jun 6, 2020 · 3 comments
Assignees

Comments

@andresgbertola
Copy link

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
@JonathanMagnan JonathanMagnan self-assigned this Jun 7, 2020
@JonathanMagnan
Copy link
Member

Hello @andresgbertola ,

Thank you for reporting,

My developer will try it with the information you provided.

Could you confirm that you got this error with InMemory or also with provided such as SQL Server?

Best Regards,

Jon


Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework ExtensionsEntity Framework ClassicBulk OperationsDapper Plus

Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval FunctionSQL Eval Function

@andresgbertola
Copy link
Author

Hello @JonathanMagnan!
Thank you so much for your reply!

In the above example, I was using an InMemory DbContext.
But after reading your reply, I tried using the SqlServer DbContext. No exception was thrown. It worked properly.
So the exception is thrown only when using InMemory DbContext.
When I said before that it was working in EF Core 2.1. I was talking about the Sql Server DbContext.
I havent try it using the InMemory one. Maybe this wasnt working in the early version either.

Just in case, I´m using the lastest version of System.Linq.Dynamic.Core package (v1.1.2).

Thanks!

@JonathanMagnan
Copy link
Member

Hello @andresgbertola ,

We checked to fix it for InMemory but it looks more an issue inside the provider than an issue inside our library and as you noticed, it works fine with SQL Server.

I did some test with some version released 1-2 years ago, we get the same issue.

So we will close this issue as I don't think there is anything we can do on our side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants