Efcore: Query: Filter out entities that are using table splitting with a derived type

Created on 26 Jun 2017  路  10Comments  路  Source: dotnet/efcore

Entities that are splitting the table with a derived type need to be queried with a filter on the principal type discriminator.

See TableSplittingTestBase.Can_query_shared_derived() and OwnedQuerySqlServerTest

closed-fixed punted-for-2.0 type-enhancement

Most helpful comment

I'll add a validation rule for 2.0 so we don't waste time on a temporary solution.

All 10 comments

@AndriySvyryd What does this mean?

@anpete It will make more sense when https://github.com/aspnet/EntityFramework/pull/8976 is checked in

I think we should consider reworking discriminators to be in-terms of QueryModel rewrites (like entity filters).

@anpete to write a note on details.
@smitpatel We should either fix this or throw an exception in, for example, model validation so we can fix it post 2.0 without it being a breaking change. Please don't take a long time on a complex fix--if the fix isn't simple, then let's go the throw route.

@smitpatel The fix to try is to modify the two places in relational that apply discriminator predicates to SelectExpression: MaterializerFactory.CreateMaterializer and RelationalEntityQueryableExpressionVisitor.DiscriminateProjectionQuery. What we need to do is expand the cases for when we introduce discriminators by taking into account any related principal ETs that are sharing the same table. E.g. For model:

  /
B --> C

Where B inherits A ,and B references C, and A, B, C all share the same table, then any direct query for Cs necessarily needs to have a B's discriminator predicate applied. Note, no join should be required because we are always table splitting.

@AndriySvyryd has some context on this, too.

@anpete - I prefer the idea of converting discriminators to where predicates at query model level. At present, we are in the world where creating SelectExpression for EntityQueryable can give rise to "where" clause in Select. That causes issues with joins where a flat QM can also generated a complex Select which requires to be pushdown.
https://github.com/aspnet/EntityFramework/blob/f034d5d18e57667e6b9af2424f8e6676340bae77/src/EFCore.Relational/Query/RelationalQueryModelVisitor.cs#L1537
Above code special case it for Left join cases.
And we still have bug for https://github.com/aspnet/EntityFramework/issues/8375

Both above manifest from the fact that a random where predicate can arise for TPH scenario. With table splitting like above, that case becomes even more expanded since now, a shared type of a derived type will start having where.

It would be much more easier for our translation pipeline to work, if QM is modified instead of working around while translating. Though that will be decent amount of work with not enough time and then throw becomes the solution for 2.0.

If we want to support this for 2.0, then we can go with suggestion above and make additional check for owners.

Your call what we should do for 2.0 鈱氾笍

I'll add a validation rule for 2.0 so we don't waste time on a temporary solution.

Sounds good to me.

Thanks for investigating. Validation rule seems appropriate for 2.0.

@smitpatel This is a decent amount of work, so marking as priority high for 2.1 to indicate that it should be done soon.

Was this page helpful?
0 / 5 - 0 ratings