question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Query: Include for derived types fails when source does not contain any of the derived type

See original GitHub issue

Consider a model with a base type and two different derived types. “Include for derived types” works well when the source of the query contains only the first derived type or a mix of both derived types. It fails when the source only does not contain any of the first derived type. Please look at the code example below:

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;

namespace DerivedIncludeSelectiveTest
{
	class Program
	{
		static void Main(string[] args)
		{
			using (var myContext = new MyContext())
			{
				myContext.Database.EnsureDeleted();
				myContext.Database.EnsureCreated();
				GetSchoolsWithInclude(myContext.Schools);
				GetSchoolsWithInclude(myContext.PrimarySchools);
				GetSchoolsWithInclude(myContext.Colleges); // this line throws an exception despite the "include on derived types" being supposed to apply only to the specified derived type
			}
			Console.ReadLine();
		}

		static School[] GetSchoolsWithInclude(IQueryable<School> source) =>
					source
					.Include(s => ((PrimarySchool)s).Students) // loading students only for PrimarySchools
					.ToArray();
	}

	public class MyContext : DbContext
	{
		public DbSet<PrimaryStudent> PrimaryStudents { get; set; }
		public DbSet<School> Schools { get; set; }
		public DbSet<PrimarySchool> PrimarySchools { get; set; }
		public DbSet<College> Colleges { get; set; }
		protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
		{
			optionsBuilder.UseSqlServer(@"Data Source=" + System.Environment.MachineName +
				";Initial Catalog=derivedIncludeSelectiveTest;Integrated Security=True");
			optionsBuilder.EnableSensitiveDataLogging();
			optionsBuilder.ConfigureWarnings(w => w.Log(
				Microsoft.EntityFrameworkCore.Diagnostics.CoreEventId.SensitiveDataLoggingEnabledWarning));
		}
		protected override void OnModelCreating(ModelBuilder modelBuilder)
		{
			modelBuilder.Entity<PrimarySchool>().HasMany(s => s.Students).WithOne(s => s.School);
			modelBuilder.Entity<PrimarySchool>().HasData(new PrimarySchool { Id = 1 });
			modelBuilder.Entity<College>().HasData(new College { Id = 2 });
		}
	}

	public class PrimaryStudent
	{
		public int Id { get; set; }
		public PrimarySchool School { get; set; }
	}

	public abstract class School // base type
	{
		public int Id { get; set; }
	}

	public class PrimarySchool : School // first derived type
	{
		public List<PrimaryStudent> Students { get; set; }
	}

	public class College : School // second derived type
	{
		// does not have an association to students
	}
}

In EF 3.0, it throws:

System.InvalidOperationException
  HResult=0x80131509
  Message=Invalid include.
  Source=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.PopulateIncludeTree(IncludeTreeNode includeTreeNode, Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessInclude(NavigationExpansionExpression source, Expression expression, Boolean thenInclude)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ExpandAndReduce(Expression query, Boolean applyInclude)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
   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 Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IncludableQueryable`2.GetEnumerator()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at DerivedIncludeSelectiveTest.Program.GetSchoolsWithInclude(IQueryable`1 schools) 

In EF 2.2.6, it throws:

System.InvalidOperationException
  HResult=0x80131509
  Message=The property 'Students' is not a navigation property of entity type 'College'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.
  Source=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler.WalkNavigations(IEntityType entityType, IReadOnlyList`1 navigationPropertyPaths, IncludeLoadTree includeLoadTree, Boolean shouldThrow)
   at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler.TryPopulateIncludeLoadTree(IncludeResultOperator includeResultOperator, IncludeLoadTree includeLoadTree, Boolean shouldThrow)
   at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler.CreateIncludeLoadTrees(QueryModel queryModel, Boolean shouldThrow)
   at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler.CompileIncludes(QueryModel queryModel, Boolean trackingQuery, Boolean asyncQuery, Boolean shouldThrow)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   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 Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IncludableQueryable`2.GetEnumerator()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at DerivedIncludeSelectiveTest.Program.GetSchoolsWithInclude(IQueryable`1 schools) 

Further technical details

EF Core version: 2.2.6 and 3.0 (different errors in each) Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: NET Core 3.0 Operating system: Windows 10 x64 Pro 1903 IDE: Visual Studio 2019 16.3.4

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
smitpatelcommented, Oct 15, 2019
static School[] GetSchoolsWithInclude<T>(IQueryable<T> source)
            where T : School
        {
            if (typeof(T) == typeof(School)
                || typeof(T) == typeof(PrimarySchool))
            {
                source = source.Include(e => (e as PrimarySchool).Students);
            }

            return source.ToArray();
        }

// Use as 
GetSchoolsWithInclude(db.Schools);
                GetSchoolsWithInclude(db.PrimarySchools);
                GetSchoolsWithInclude(db.Colleges);
0reactions
vsleecommented, Oct 15, 2019

Great, thanks for the guidance

Read more comments on GitHub >

github_iconTop Results From Across the Web

Query: Include for derived types fails when source does not ...
"Include for derived types" works well when the source of the query contains only the first derived type or a mix of both...
Read more >
Conditionally query related entities with derived types ...
The problem is that it works if the condition uses entity primitive properties, but fails with navigation properties because at the time client ......
Read more >
Derived Types
A derived type is a special form of data type that can encapsulate other ... Furthermore it cannot contain any Fortran pointer or...
Read more >
The Expression is not valid in an include function
Hi im trying to get some data from the foreign key column and when i use the then include operation i get the...
Read more >
Great grandchildren ThenInclude() is failing - Microsoft Q&A
I have the following query. In the code it's Signup.Effort.Parent var user = await context.AppUsers .Include(user => user.Following!) .
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found