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

ThenInclude fails with ArgumentNullException for the navigation of base class which is not added as entity type #3994

Closed
zilloy opened this issue Dec 7, 2015 · 2 comments
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@zilloy
Copy link

zilloy commented Dec 7, 2015

I have the following classes

public class ClassA
    {
        public ICollection<ClassB> BItems { get; set; }
    }

public class ClassB: GenericClass<ClassA>
    {

    }

public class GenericClass<T>
    {
        public ICollection<ClassC> CItems{ get; set; }
    }

public class ClassC
    {

    }

When I try to execute the following statement it fails with ArgumentNullException

return _dbContext.Set<ClassA>()
                .Include(x => x.BItems)
                .ThenInclude(x => x.CItems)
                .SingleOrDefaultAsync(x => x.Id == id, cancellationToken);

Here is the stack trace

   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.<>c__DisplayClass43_0.<IncludeNavigations>b__1(IEnumerable`1 ps, IQuerySource _)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindMemberExpressionCore[TResult](MemberExpression memberExpression, IQuerySource querySource, Func`3 memberBinder)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.BindNavigationPathMemberExpression[TResult](MemberExpression memberExpression, Func`3 memberBinder)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.<IncludeNavigations>b__43_0(IncludeQueryAnnotation annotation)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.IncludeNavigations(QueryModel queryModel)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.Data.Entity.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel)
   at Microsoft.Data.Entity.Query.QueryCompiler.<>c__DisplayClass17_0`1.<CompileAsyncQuery>b__0()
   at Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.Data.Entity.Query.QueryCompiler.CompileAsyncQuery[TResult](Expression query)
   at Microsoft.Data.Entity.Query.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, LambdaExpression expression, CancellationToken cancellationToken)
   at Microsoft.Data.Entity.EntityFrameworkQueryableExtensions.SingleOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)

EDIT: It also failed when I tried to make GenericClass non-generic. I guess it happened because of CItems collection

@rowanmiller
Copy link
Contributor

Repro'd on the latest bits. Seems to be related to having a navigation defined on an unmapped base type. Below is a runnable repro. If BaseClass is pulled into the model, then the query succeeds. It's also not as basic as just including any nav prop on an unmapped base type, as querying for ClassB and Including CItems works fine.

using Microsoft.Data.Entity;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var db = new SampleContext())
            {
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                var a = new ClassA
                {
                    BItems = new List<ClassB>
                    {
                        new ClassB
                        {
                            CItems = new List<ClassC>
                            {
                                new ClassC()
                            }
                        }
                    }
                };

                db.Add(a);
                db.Add(a.BItems.Single());
                db.Add(a.BItems.Single().CItems.Single());
                db.SaveChanges();
            }

            using (var db = new SampleContext())
            {
                var id = 1;

                var a = db.Set<ClassA>()
                    .Include(x => x.BItems)
                    .ThenInclude(x => x.CItems)
                    .SingleOrDefaultAsync(x => x.Id == id);
            }
        }
    }

    public class SampleContext : DbContext
    {
        public DbSet<ClassA> ClassAs { get; set; }
        public DbSet<ClassB> ClassBs { get; set; }
        public DbSet<ClassC> ClassCs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder builder)
        {
            builder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Samples;Trusted_Connection=True;");
        }
    }

    public class ClassA
    {
        public int Id { get; set; }
        public ICollection<ClassB> BItems { get; set; }
    }

    public class ClassB : BaseClass
    {
    }

    public class BaseClass
    {
        public int Id { get; set; }
        public ICollection<ClassC> CItems { get; set; }
    }

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

@smitpatel
Copy link
Contributor

The issue is when we work with chained navigations, we find the declaring type in our model to get the navigation from property info. If the navigation is declared on base type which is not included in the model then navigation is not found and ArgumentNullException is thrown.

@smitpatel smitpatel assigned smitpatel and unassigned maumar Jan 14, 2016
@smitpatel smitpatel modified the milestones: 7.0.0-rc2, 7.0.0 Jan 14, 2016
@smitpatel smitpatel changed the title ThenInclude fails with ArgumentNullException for generic items collection ThenInclude fails with ArgumentNullException for the navigation of base class which is not added as entity type Jan 19, 2016
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 15, 2022
@ajcvickers ajcvickers modified the milestones: 1.0.0-rc2, 1.0.0 Oct 15, 2022
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. type-bug
Projects
None yet
Development

No branches or pull requests

5 participants