Skip to content

Query: client method around qsre followed by projecting collection navigation throws during compilation #12697

@maumar

Description

@maumar

Found when working on workaround for #12678

repro:

            using (var ctx = new MyContext())
            {
                ctx.Database.EnsureDeleted();
                ctx.Database.EnsureCreated();

                var check = new Check { CheckTemplateId = 1 };

                var examiner1 = new Examiner();
                var examiner2 = new Examiner();

                var user1 = new User();
                var implementer1 = new Implementer { User = user1 };

                var user2 = new User();
                var implementer2 = new Implementer { User = user2 };

                var template = new CheckTemplate { Description = "1", Examiners = new List<Examiner> { examiner1, examiner2 }, Implementers = new List<Implementer> { implementer1, implementer2 } };

                ctx.Checks.Add(check);
                ctx.Examiners.AddRange(examiner1, examiner2);
                ctx.Users.AddRange(user1, user2);
                ctx.Implementers.AddRange(implementer1, implementer2);
                ctx.CheckTemplates.Add(template);
                ctx.SaveChanges();
            }

            using (var db = new MyContext())
            {
                var checkId = 1;

                var data = (from c in db.Checks
                                 join ct in db.CheckTemplates
                                      .Include(a => a.Implementers).ThenInclude(u => u.User)
                                 on c.CheckTemplateId equals ct.CheckTemplateId
                                 where c.CheckId == checkId
                                 select new
                                 {
                                     CheckId = c.CheckId,
                                     Description = ct.Description,
                                     Implementers = Client(ct).Implementers,
                                     NumExaminers = ct.Examiners.Count
                                 }).FirstOrDefault();
            }
        }

        public static T Client<T>(T s) => s;

        public static List<Implementer> ProjectImplementers(CheckTemplate checkTemplate) => checkTemplate.Implementers;

        public static TResult ClientProject<TSource, TResult>(TSource source, Func<TSource, TResult> selector) => selector(source);
    }

    public class Check
    {
        public int CheckId { get; set; }

        public int CheckTemplateId { get; set; }
    }

    public class CheckTemplate
    {
        public int CheckTemplateId { get; set; }
        public string Description { get; set; }

        public List<Implementer> Implementers { get; set; }

        public List<Examiner> Examiners { get; set; }
    }

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

    public class Implementer
    {
        public int Id { get; set; }
        public User User { get; set; }
    }

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

    public class MyContext : DbContext
    {
        public DbSet<Check> Checks { get; set; }

        public DbSet<CheckTemplate> CheckTemplates { get; set; }

        public DbSet<Examiner> Examiners { get; set; }

        public DbSet<User> Users { get; set; }

        public DbSet<Implementer> Implementers { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=.;Database=Repro12678;Trusted_Connection=True;MultipleActiveResultSets=True");
        }
    }

exception:

System.ArgumentNullException: 'Value cannot be null.'

   at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName) in D:\git\EntityFrameworkCore\src\Shared\Check.cs:line 28
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.RegisterCorrelatedSubqueryMetadata(MainFromClause mainFromClause, Boolean trackingQuery, INavigation firstNavigation, INavigation collectionNavigation, IQuerySource parentQuerySource) in D:\git\EntityFrameworkCore\src\EFCore\Query\QueryCompilationContext.cs:line 96
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.CorrelatedCollectionFindingExpressionVisitor.<>c__DisplayClass7_0.<TryMarkSubQuery>b__0(IReadOnlyList`1 properties, IQuerySource querySource) in D:\git\EntityFrameworkCore\src\EFCore\Query\ExpressionVisitors\Internal\CorrelatedCollectionFindingExpressionVisitor.cs:line 111
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.BindPropertyExpressionCore[TResult](Expression propertyExpression, IQuerySource querySource, Func`3 propertyBinder) in D:\git\EntityFrameworkCore\src\EFCore\Query\EntityQueryModelVisitor.cs:line 1825
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.BindNavigationPathPropertyExpression[TResult](Expression propertyExpression, Func`3 propertyBinder) in D:\git\EntityFrameworkCore\src\EFCore\Query\EntityQueryModelVisitor.cs:line 1723
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.CorrelatedCollectionFindingExpressionVisitor.TryMarkSubQuery(SubQueryExpression expression) in D:\git\EntityFrameworkCore\src\EFCore\Query\ExpressionVisitors\Internal\CorrelatedCollectionFindingExpressionVisitor.cs:line 103
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.CorrelatedCollectionFindingExpressionVisitor.VisitMethodCall(MethodCallExpression node) in D:\git\EntityFrameworkCore\src\EFCore\Query\ExpressionVisitors\Internal\CorrelatedCollectionFindingExpressionVisitor.cs:line 75
   at System.Linq.Expressions.MethodCallExpression.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.VisitAndConvert[T](ReadOnlyCollection`1 nodes, String callerName)
   at Remotion.Linq.Parsing.RelinqExpressionVisitor.VisitNew(NewExpression expression)
   at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Remotion.Linq.Clauses.SelectClause.TransformExpressions(Func`2 transformation)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery) in D:\git\EntityFrameworkCore\src\EFCore\Query\EntityQueryModelVisitor.cs:line 338
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery) in D:\git\EntityFrameworkCore\src\EFCore.Relational\Query\RelationalQueryModelVisitor.cs:line 1345
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel) in D:\git\EntityFrameworkCore\src\EFCore\Query\EntityQueryModelVisitor.cs:line 170
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel) in D:\git\EntityFrameworkCore\src\EFCore\Storage\Database.cs:line 70
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger`1 logger, Type contextType) in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\QueryCompiler.cs:line 126
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass13_0`1.<Execute>b__0() in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\QueryCompiler.cs:line 91
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler) in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\CompiledQueryCache.cs:line 67
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler) in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\CompiledQueryCache.cs:line 44
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\QueryCompiler.cs:line 87
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) in D:\git\EntityFrameworkCore\src\EFCore\Query\Internal\EntityQueryProvider.cs:line 62
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at Repro12678.Program.Main(String[] args) in D:\Projects\Repro12678\Repro12678\Program.cs:line 42

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions