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

Valid query throws ArgumentException #14991

Closed
JoasE opened this issue Mar 12, 2019 · 5 comments
Closed

Valid query throws ArgumentException #14991

JoasE opened this issue Mar 12, 2019 · 5 comments
Labels
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

@JoasE
Copy link

JoasE commented Mar 12, 2019

A valid LINQ query which works over a List throws an System.ArgumentException when querying over a DbSet.

The expression is copied from an expression generated by AutoMapper, but the expression should be valid.

Moved from: AutoMapper/AutoMapper#3010

Exception message: System.ArgumentException: `Argument types do not match`
Stack trace: at System.Linq.Expressions.Expression.Bind(MemberInfo member, Expression expression)
   at System.Linq.Expressions.MemberAssignment.Update(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](ReadOnlyCollection`1 nodes, String callerName)
   at Remotion.Linq.Parsing.RelinqExpressionVisitor.VisitNew(NewExpression expression)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.VisitNew(NewExpression newExpression)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Remotion.Linq.Clauses.SelectClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalEntityQueryableExpressionVisitor.VisitSubQuery(SubQueryExpression expression)
   at Remotion.Linq.Clauses.Expressions.SubQueryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalEntityQueryableExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
   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.Query.EntityQueryModelVisitor.ReplaceClauseReferences(Expression expression, IQuerySource querySource, Boolean inProjection)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Remotion.Linq.Clauses.SelectClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger`1 logger, Type contextType)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass13_0`1.<Execute>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.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at ConsoleApp5.Program.Main(String[] args) in C:\Users\Joas\source\repos\ConsoleApp5\ConsoleApp5\Program.cs:line 47

Steps to reproduce

https://github.com/JoasE/AutoMapperRepro

var manualQuery = context.Users.Select(dtoUser => new User.ViewDto
{
	Id = dtoUser.Id,
	Posts = dtoUser.Posts
		.Select(
			dtoPost => new Object_205617611___LastComment_Id_Text_UserId
			{
				__LastComment = dtoPost.Comments.LastOrDefault(),
				Id = dtoPost.Id,
				Text = dtoPost.Text,
				UserId = dtoPost.UserId
			})
		.Select(
			dtoLet => new Post.ViewDto
			{
				Id = dtoLet.Id,
				LastComment = (dtoLet.__LastComment == null)
					? null
					: new Comment.ViewDto
					{
						Id = dtoLet.__LastComment.Id,
						PostId = dtoLet.__LastComment.PostId,
						Text = dtoLet.__LastComment.Text
					},
				Text = dtoLet.Text,
				UserId = dtoLet.UserId
			})
		.ToList()
}).FirstOrDefault(x => x.Id == user.Id);

Further technical details

EF Core version: 2.2.2
Database Provider: Microsoft.EntityFrameworkCore.SqlServer 2.2.2
Operating system: Windows 10
IDE: Visual Studio 2017 15.9.6

@gsGabriel
Copy link

I have the same issue... But with the Npgsql.EntityFrameworkCore.PostgreSQL 2.2.0

@JoasE
Copy link
Author

JoasE commented May 6, 2019

@gsGabriel Are you sure it's the same issue? Is your query and data structure similar to mine? Could you share your reproduce steps? It might help the guys debug and fix this issue.

@gsGabriel
Copy link

Yes, I am sure, the data structure is not exactly the same but it is very close... Follows the sample that resembles my

var manualQuery = await context.Users.Include(x => x.UsersPosts).ThenInclude(x => x.Posts)
.Select(dtoUser => new User.ViewDto
{
	Posts = dtoUser.UsersPosts.Posts.Select(dtoPost  => new Post.ViewDto { dtoPost.Id })
}).ToArrayAsync();

@gsGabriel
Copy link

gsGabriel commented May 6, 2019

To solve, i broke between two queries, the first to get the posts, on the second query i`m used the posts results to binding a dto.

@divega divega modified the milestones: 3.0.0, Backlog Jun 21, 2019
@smitpatel smitpatel removed their assignment Jun 24, 2019
@JoasE
Copy link
Author

JoasE commented Oct 3, 2019

I've tested this and can confirm this has been fixed as of EntityFramework 3.0.0, with some changes made to the query.

When I ran the original code in 3.0.0 I would get an exception:

System.InvalidOperationException: 'The LINQ expression 'LastOrDefault<Nullable<Guid>>(Select<Comment, Nullable<Guid>>(
    source: Where<Comment>(
        source: DbSet<Comment>, 
        predicate: (c) => Property<Nullable<Guid>>(EntityShaperExpression: 
            EntityType: Post
            ValueBufferExpression: 
                ProjectionBindingExpression: EmptyProjectionMember
            IsNullable: False
        , "Id") == Property<Nullable<Guid>>(c, "PostId")), 
    selector: (c) => Property<Nullable<Guid>>(c, "Id")))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'

After a quick google search I found this issue, so I realized I could change the query in order for it to work:

var manualQuery = context.Users.Select(dtoUser => new User.ViewDto
{
    Id = dtoUser.Id,
    Posts = dtoUser.Posts
        .Select(
            dtoPost => new Object_205617611___LastComment_Id_Text_UserId
            {
                __LastComment = dtoPost.Comments.OrderBy(x => x.CreatedAt).LastOrDefault(), // I have added the CreatedAt property
                Id = dtoPost.Id,
                Text = dtoPost.Text,
                UserId = dtoPost.UserId
            })
        .Select(
            dtoLet => new Post.ViewDto
            {
                Id = dtoLet.Id,
                LastComment = (dtoLet.__LastComment == null)
                    ? null
                    : new Comment.ViewDto
                    {
                        Id = dtoLet.__LastComment.Id,
                        PostId = dtoLet.__LastComment.PostId,
                        Text = dtoLet.__LastComment.Text
                    },
                Text = dtoLet.Text,
                UserId = dtoLet.UserId
            })
        .ToList()
}).FirstOrDefault(x => x.Id == user.Id);

or

__LastComment = dtoPost.Comments.OrderByDescending(x => x.CreatedAt).FirstOrDefault(), 

My thanks to the team and any contributors who might have helped for fixing this issue.

@JoasE JoasE closed this as completed Oct 3, 2019
@smitpatel smitpatel modified the milestones: Backlog, 3.0.0 Oct 3, 2019
@smitpatel smitpatel added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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

5 participants