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

"Argument types do not match" when using cast in where clause #13093

Closed
genne opened this issue Aug 23, 2018 · 2 comments
Closed

"Argument types do not match" when using cast in where clause #13093

genne opened this issue Aug 23, 2018 · 2 comments

Comments

@genne
Copy link

genne commented Aug 23, 2018

I've been trying to migrate from EF 6 to EF core, but can't figure out how to handle this case (simplified example, see full example below):

myContext.Blogs.Select(blog => new BlogDto()
{
  Id = blog.Id,
  Post = blog.Posts.FirstOrDefault(),
})
.Where(s => ((IEntity) s).Id == 1)
.Select(p => p.Id)

When running I get the following exception (unfortunately exception message is in Swedish, but should be same as "Argument types do not match"):

System.ArgumentException
  HResult=0x80070057
  Message=Argumenttyperna matchar inte
  Source=System.Core
  StackTrace:
   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 System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalEntityQueryableExpressionVisitor.VisitMember(MemberExpression node)
   at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.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.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
   at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
   at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, 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 Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at EFSampleApp.Program.Main()

If I comment out any of the above lines in the code above it works, also if I avoid casting to IEntity in the Where clause.

(The actual code is a lot more complex, and I know this particular example could be simplified a lot, but we're using generic helper methods that does most of this for us, and I would like to keep it that way. The example code is just to reproduce the exception.)

Steps to reproduce

using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace EFSampleApp
{
    public class Program
    {
        public static void Main()
        {
            var myContext = new MyContext();
            myContext.Database.EnsureDeleted();
            myContext.Database.EnsureCreated();
            var blogs = myContext.Blogs.Select(blog => new BlogDto()
                {
                    Id = blog.Id,
                    Post = blog.Posts.FirstOrDefault(),
                })
                .Where(s => ((IEntity) s).Id == 1)
                .Select(p => p.Id)
                .ToArray();
        }
    }
    public class MyContext : DbContext
    {
        // Declare DBSets
        public DbSet<Blog> Blogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseSqlServer(
                    @"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
                .EnableSensitiveDataLogging();
        }
    }

    public interface IEntity
    {
        int Id { get; }
    }

    public class Blog
    {
        public int Id { get; set; }
        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int Id { get; set; }
    }

    public class BlogDto : IEntity
    {
        public int Id { get; set; }
        public Post Post { get; set; }
    }
}

Further technical details

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

@smitpatel
Copy link
Contributor

Error in 3.1

Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet<Blog>                                                                                                                                                                                                                                  
    .Where(b => ((IEntity)new BlogDto{                                                                                                                                                                                                                                                                                   
        Id = b.Id,                                                                                                                                                                                                                                                                                                       
        Post = DbSet<Post>                                                                                                                                                                                                                                                                                               
            .Where(p => EF.Property<Nullable<int>>(b, "Id") != null && EF.Property<Nullable<int>>(b, "Id") == EF.Property<Nullable<int>>(p, "BlogId"))                                                                                                                                                                   
            .FirstOrDefault()                                                                                                                                                                                                                                                                                            
    }                                                                                                                                                                                                                                                                                                                    
    ).Id == 1)' 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.   

We should try to fix this.

@smitpatel
Copy link
Contributor

Duplicate of #20097

@smitpatel smitpatel marked this as a duplicate of #20097 Mar 16, 2020
@smitpatel smitpatel removed this from the Backlog milestone Mar 16, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants