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

GroupBy causes exception #20887

Open
Tracked by #30173
DenisMayorko opened this issue May 8, 2020 · 6 comments
Open
Tracked by #30173

GroupBy causes exception #20887

DenisMayorko opened this issue May 8, 2020 · 6 comments

Comments

@DenisMayorko
Copy link

"Group" operation throws error with list preselect. It happends both at anonymous type or created dto.

We have library that handled entities after our select operation to dto by applying its own pagination, group, sort and select, but now group causes error.

I don't see any explanation why it can't be translated to sql and didn't find any same created issues.

Steps to reproduce

namespace Test
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var context = new ModuleDbContext(new DbContextOptionsBuilder<ModuleDbContext>()
               .UseNpgsql("Host=localhost;Port=5432;Database=sandBox")
               .Options);
            var users = context.Entities.Include(x => x.List)
                .Select(x => new { x.Id, x.List }) //List causes error
                .GroupBy(x => x.Id, (x, y) => new { x })
                .ToList(); //error throws here
        }
    }

    public class ModuleDbContext : DbContext
    {
        public ModuleDbContext(DbContextOptions<ModuleDbContext> options) : base(options)
        {
        }

        public DbSet<Entity> Entities { get; set; }
        public DbSet<ListEntity> ListEntities { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<ListEntity>().HasOne(x => x.Entity).WithMany(x => x.List);
        }
    }

    public class Entity
    {
        [Key]
        public int Id { get; set; }
        public List<ListEntity> List { get; set; }
    }
    public class ListEntity
    {
        [Key]
        public int Id { get; set; }
        public Entity Entity { get; set; }
    }
}

Exception

  • Npgsql
System.InvalidCastException
  HResult=0x80004002
  Сообщение = Unable to cast object of type 'Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression' to type 'System.Linq.Expressions.ConstantExpression'.
  Источник = Microsoft.EntityFrameworkCore.Relational
  Трассировка стека:
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.Visit(Expression node, IReadOnlyList`1& projectionColumns)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.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__DisplayClass9_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 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Test.Program.<Main>d__0.MoveNext() in E:\repos\Athena.Test\Test\Test\Program.cs:line 21
  • InMemory
System.InvalidCastException
  HResult=0x80004002
  Сообщение = Unable to cast object of type 'System.Linq.Expressions.MethodCallExpression3' to type 'System.Linq.Expressions.ConstantExpression'.
  Источник = Microsoft.EntityFrameworkCore.InMemory
  Трассировка стека:
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.GetProjectionIndex(InMemoryQueryExpression queryExpression, ProjectionBindingExpression projectionBindingExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.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__DisplayClass9_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 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Test.Program.<Main>d__0.MoveNext() in E:\repos\Athena.Test\Test\Test\Program.cs:line 21

Further technical details

EF Core version: 3.0+ (also tested with 5.0 preview)
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL (also Microsoft.EntityFrameworkCore.InMemory, but another exception)
Target framework: .NET Core 3.1 (also tested with 5.0 preview)
Operating system: Windows 10
IDE: Visual Studio Community 2019 16.5.4, 16.6.6 Preview 6

@DenisMayorko DenisMayorko changed the title GroupBy couses exception GroupBy causes exception May 8, 2020
@DenisMayorko
Copy link
Author

Test project to reproduce

@smitpatel
Copy link
Member

Duplicate of #19929

@smitpatel smitpatel marked this as a duplicate of #19929 May 8, 2020
@powermetal63
Copy link

powermetal63 commented May 16, 2020

@smitpatel Here

.GroupBy(x => x.Id, (x, y) => new { x })

x in the projection new { x } is the grouping Key, hence I don't think this falls into #19929 ("Support GroupBy when it is final operator"), but translation bug - GroupBy selecting key / aggregates is supposed to be supported. There are no navigation properties or correlated collections involved in the grouping result projection, just the grouping source contains correlated collection projection.

Also inserting

.Select(x => new { x.Id })

before GroupBy fixes the problem.

Also there is similar (same) issue posted on StackOverflow - GroupBy with after projection to domain model without .ToList().

I'm not sure if resolving #19929 will resolve this or not, so consider reopening this as a bug.

@smitpatel
Copy link
Member

x.List introduces client eval causing binding error during GroupBy. Easy work-around would be to remove x.List from query which is not used in GroupBy or final result.

@DenisMayorko
Copy link
Author

x.List introduces client eval causing binding error during GroupBy. Easy work-around would be to remove x.List from query which is not used in GroupBy or final result.

"GroupBy" may be used or not. It depending on parameters coming to the controller and handles with library DevExtreme.

The current workaround is the creation of two methods: with and without group. But I think it is obviously that it should be just ignored without manual handling

@snieking
Copy link

snieking commented Jun 5, 2020

I ran into a very similar issue, and here is a sample app that reproduces it via DevExpress:
https://github.com/snieking/DevExpress-DataSourceLoader-issue

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

5 participants