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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions