Skip to content

EntityCommandCompilationException when using .Include() on class with subclass #159

@jehhynes

Description

@jehhynes

Description

When using DbSet.Include(x => x.Relationship) where Relationship is a type which has a subclass, we receive a EntityCommandCompilationException.

I've included the full exception below, and a test case which will run in the DynamicFiltersTests project (and fail with the following exception). This is using the latest codebase on master.

Exception

 Message: 
    Test method DynamicFiltersTests.NavigationTests.FilterIncludesWithSubclass threw exception: 
    System.Data.Entity.Core.EntityCommandCompilationException: An error occurred while preparing the command definition. See the inner exception for details. ---> System.ArgumentException: The specified navigation requires a navigation source of a type that is compatible with 'Transient.reference[DynamicFiltersTests.Employee]'.
    Parameter name: from
  Stack Trace: 
    at ArgumentValidation.RequireCompatibleType(DbExpression from, RelationshipEndMember end, Boolean allowAllRelationshipsInSameTypeHierarchy)
    at ArgumentValidation.ValidateNavigate(DbExpression navigateFrom, RelationshipEndMember fromEnd, RelationshipEndMember toEnd, RelationshipType& relType, Boolean allowAllRelationshipsInSameTypeHierarchy)
    at DbExpressionBuilder.Navigate(DbExpression navigateFrom, RelationshipEndMember fromEnd, RelationshipEndMember toEnd)
    at DefaultExpressionVisitor.Visit(DbRelationshipNavigationExpression expression)
    at DbRelationshipNavigationExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
    at DefaultExpressionVisitor.VisitExpression(DbExpression expression)
    at DefaultExpressionVisitor.VisitList[TElement](IList`1 list, Func`2 map)
    at DefaultExpressionVisitor.VisitExpressionList(IList`1 list)
    at DefaultExpressionVisitor.Visit(DbNewInstanceExpression expression)
    at DynamicFilterQueryVisitorCSpace.Visit(DbNewInstanceExpression expression) in DynamicFilterQueryVisitorCSpace.cs line: 396
    at DbNewInstanceExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
    at DefaultExpressionVisitor.VisitExpression(DbExpression expression)
    at DefaultExpressionVisitor.VisitList[TElement](IList`1 list, Func`2 map)
    at DefaultExpressionVisitor.VisitExpressionList(IList`1 list)
    at DefaultExpressionVisitor.Visit(DbNewInstanceExpression expression)
    at DynamicFilterQueryVisitorCSpace.Visit(DbNewInstanceExpression expression) in DynamicFilterQueryVisitorCSpace.cs line: 396
    at DbNewInstanceExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
    at DefaultExpressionVisitor.VisitExpression(DbExpression expression)
    at DefaultExpressionVisitor.Visit(DbProjectExpression expression)
    at DynamicFilterQueryVisitorCSpace.Visit(DbProjectExpression expression) in DynamicFilterQueryVisitorCSpace.cs line: 418
    at DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
    at DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext) in DynamicFilterInterceptor.cs line: 43
    at DbCommandTreeDispatcher.<Created>b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c)
    at InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept)
    at DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
    at DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
    at ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
    at  --- End of inner exception stack trace ---
    at ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
    at ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
    at EntitySqlQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
    at <>c__DisplayClass7.<GetResults>b__6()
    at ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
    at <>c__DisplayClass7.<GetResults>b__5()
    at DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
    at ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
    at IEnumerable<T>.GetEnumerator>b__0()
    at LazyEnumerator`1.MoveNext()
    at List`1.ctor(IEnumerable`1 collection)
    at Enumerable.ToList[TSource](IEnumerable`1 source)
    at NavigationTests.FilterIncludesWithSubclass() in NavigationTests.cs line: 21
Exception message:
Stack trace:

Fiddle or Project

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using EntityFramework.DynamicFilters;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DynamicFiltersTests
{
    [TestClass]
    public class NavigationTests
    {

        [TestMethod]
        public void FilterIncludesWithSubclass()
        {
            using (var context = new TestContext())
            {
                var list = context.Entity1s
                    .Include(x => x.User)
                    .ToList();
            }
        }
        
        #region Models

        public class Depot : PersistentObject, IFilterTenant
        {
            public virtual Tenant Tenant { get; set; }
        }

        public class Employee : UserAccount
        {
            public virtual Depot Depot { get; set; }
        }

        public class UserAccount : PersistentObject, IFilterTenant
        {
            public virtual Tenant Tenant { get; set; }
        }

        public class Entity1 : PersistentObject, IFilterTenant
        {
            [ForeignKey("Id")]
            public virtual UserAccount User { get; set; }
            public virtual Tenant Tenant { get; set; }
        }
        
        public class Tenant : PersistentObject
        {

        }

        public interface IPersistentObject
        {
            long Id { get; set; }
        }

        public abstract class PersistentObject : IPersistentObject
        {
            [Key]
            public virtual long Id { get; set; }
        }

        #endregion

        #region TestContext

        public class TestContext : TestContextBase<TestContext>, ITestContext
        {
            public long? FilterTenantId { get; set; }

            public DbSet<Tenant> Tenants { get; set; }
            public DbSet<UserAccount> UserAccounts { get; set; }
            public DbSet<Depot> Depots { get; set; }
            public DbSet<Entity1> Entity1s { get; set; }

            public override void Seed()
            {
                
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);

                modelBuilder.Filter<IFilterTenant, TestContext, long?>("TenantFilter", (o, id) => o.Tenant.Id == id, ctx => ctx.FilterTenantId);
            }
        }

        public interface IHasTenant
        {
            Tenant Tenant { get; set; }
        }
        public interface IFilterTenant : IHasTenant { }

        #endregion
    }
}


Further technical details

  • EF version: 6.1.3 (what's currently referenced on master)
  • EF DynamicFilters version: Current 'master' branch
  • Database Provider: mssqllocaldb (probably any provider)

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions