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

Query: In TPH inheritance, int discriminator does not work, exception is thrown when compiling query #7359

Closed
Dixin opened this issue Jan 5, 2017 · 4 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

@Dixin
Copy link

Dixin commented Jan 5, 2017

In TPH inheritance, string discriminator works, but int discriminator does not work.

modelBuilder.Entity<SupplierTransaction>()
    .HasDiscriminator<int>("PaymentMethodID")
    .HasValue<CashTransactiony>(1)
    .HasValue<CheckTransaction>(2)
    .HasValue<CreditCardTransaction>(3)
    .HasValue<FundsTransferTransaction>(4);

When querying SupplierTansactions table, EF Core throws InvalidOperationException when compiling the query:

The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'.
at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)
at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.TypeIsExpressionTranslatingVisitor.<>c__DisplayClass3_0.b__0(IEntityType concreteEntityType) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore.Relational\Query\RelationalQueryModelVisitor.cs:line 1247
at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
at System.Linq.Enumerable.Aggregate[TSource](IEnumerable1 source, Func3 func)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.TypeIsExpressionTranslatingVisitor.VisitTypeBinary(TypeBinaryExpression typeBinaryExpression) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore.Relational\Query\RelationalQueryModelVisitor.cs:line 1244
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression node) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore\Query\ExpressionVisitors\ExpressionVisitorBase.cs:line 26
at Remotion.Linq.Clauses.WhereClause.TransformExpressions(Func`2 transformation)
at Remotion.Linq.QueryModel.TransformExpressions(Func`2 transformation)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore.Relational\Query\RelationalQueryModelVisitor.cs:line 371
at Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryModelVisitor.VisitQueryModel(QueryModel queryModel) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore.SqlServer\Query\Internal\SqlServerQueryModelVisitor.cs:line 92
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore\Query\EntityQueryModelVisitor.cs:line 259
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel) in D:\Dixin\GitHub\EntityFramework\src\Microsoft.EntityFrameworkCore\Storage\Database.cs:line 67}

The reason is, in RelationalQueryModelVisitor.TypeIsExpressionTranslatingVisitor.VisitTypeBinary method:

var discriminatorPropertyExpression = CreatePropertyExpression(typeBinaryExpression.Expression, discriminatorProperty);
// CreatePropertyExpression calls property.ClrType.MakeNullable(), so the discriminatorPropertyExpression is of type **int?**, not int.

var discriminatorPredicate
    = concreteEntityTypes
        .Select(concreteEntityType =>
            Expression.Equal( // Exception.
                discriminatorPropertyExpression, // **int?** expression.
                Expression.Constant(_relationalAnnotationProvider.For(concreteEntityType).DiscriminatorValue))) // **int** expression.
        .Aggregate((current, next) => Expression.OrElse(next, current));

The discriminator property PaymentMethodID becomes an int? property, but the discriminator value is still int value as specified. So the Expression.Equal call throws the above exception.

Any workaround for int discriminator in TPH?

@divega
Copy link
Contributor

divega commented Jan 9, 2017

@Dixin are you planning to send a PR with the fix?

@divega
Copy link
Contributor

divega commented Jan 9, 2017

@Dixin also, does this repro with some specific query or with any query?

@divega divega added this to the 1.1.1 milestone Jan 9, 2017
@divega
Copy link
Contributor

divega commented Jan 9, 2017

Assigning to 1.1.1 based on the assumption that the whole scenario of integer discriminators could be broken, although we suspect there is something specific about this model or queries that make the bug surface. We can discuss moving it to a different milestone depending on those details.

Dixin added a commit to Dixin/EntityFramework that referenced this issue Jan 9, 2017
…exception is thrown when compiling query.
@smitpatel smitpatel removed this from the 1.1.1 milestone Jan 20, 2017
@smitpatel
Copy link
Member

Removing milestone for re-triage.
The issue mainly arises due to EF.Property expression being nullable type. If the discriminator column is of value type but in shadow state then materializer throws exception. For non-shadow discriminator, materializer would work fine but for the query with predicate Where(e => e is DerivedType) it would throw exception. The same would happen for any discriminator type as long as it is non-nullable.

@rowanmiller rowanmiller added this to the 2.0.0 milestone Jan 27, 2017
@smitpatel smitpatel added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jan 31, 2017
@ajcvickers ajcvickers changed the title In TPH inheritance, int discriminator does not work, exception is thrown when compiling query Query: In TPH inheritance, int discriminator does not work, exception is thrown when compiling query May 9, 2017
@divega divega added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. labels May 10, 2017
@ajcvickers ajcvickers modified the milestones: 2.0.0-preview1, 2.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