Skip to content

Query: include doesn't work inside subqueries #8722

@maumar

Description

@maumar

query:

var query = ctx.LevelOne
                    .Where(l1 => l1.Id < 3)
                    .Select(l1 => new { foo = ctx.LevelTwo.Include(l => l.OneToMany_Optional).Where(l => l.Id > 0) });

for this query qsre inside a subquery doesn't get replaced with include expression fragment. However, even once the include fragment gets applied to subqueries (IncludeReplacingExpressionVisitor needs VisitSubquery) we produce query plans that are largely evaluated on the client, and therefore not very useful:

(QueryContext queryContext) => IEnumerable<<>f__AnonymousType128<IQueryable<Level2>>> _InterceptExceptions(
    source: IEnumerable<<>f__AnonymousType128<IQueryable<Level2>>> _Select(
        source: IOrderedEnumerable<ValueBuffer> _OrderBy(
            source: IEnumerable<ValueBuffer> _ShapedQuery(
                queryContext: queryContext, 
                shaperCommandContext: SelectExpression: 
                    SELECT 1
                    FROM [Level1] AS [l1]
                    WHERE [l1].[Id] < 3, 
                shaper: ValueBufferShaper), 
            expression: (ValueBuffer l1) => Nullable<int> GetValue(
                queryContext: queryContext, 
                entity: [l], 
                property: Level2.Id), 
            orderingDirection: Asc), 
        selector: (ValueBuffer l1) => new <>f__AnonymousType128<IQueryable<Level2>>((IQueryable<Level2>)IOrderedQueryable<Level2> _ToQueryable(
                source: IEnumerable<Level2> _Where(
                    source: IEnumerable<Level2> _ShapedQuery(
                        queryContext: queryContext, 
                        shaperCommandContext: SelectExpression: 
                            SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_InverseId], [l].[OneToMany_Optional_Self_InverseId], [l].[OneToMany_Required_InverseId], [l].[OneToMany_Required_Self_InverseId], [l].[OneToOne_Optional_PK_InverseId], [l].[OneToOne_Optional_SelfId]
                            FROM [Level2] AS [l], 
                        shaper: BufferedEntityShaper<Level2>), 
                    predicate: (Level2 l) => Level2 _Include(
                        queryContext: queryContext, 
                        entity: l, 
                        included: new object[]{ }, 
                        fixup: (QueryContext queryContext | Level2 entity | Object[] included) => 
                        {
                            return Void queryContext.QueryBuffer.IncludeCollection(
                                includeId: 0, 
                                navigation: Level2.OneToMany_Optional, 
                                inverseNavigation: Level3.OneToMany_Optional_Inverse, 
                                targetEntityType: EntityType: Level3, 
                                clrCollectionAccessor: ClrICollectionAccessor<Level2, ICollection<Level3>, Level3>, 
                                inverseClrPropertySetter: ClrPropertySetter<Level3, Level2>, 
                                tracking: False, 
                                instance: entity, 
                                valuesFactory: () => IEnumerable<Level3> _Select(
                                    source: IOrderedEnumerable<TransparentIdentifier<Level3, AnonymousObject>> _OrderBy(
                                        source: IEnumerable<TransparentIdentifier<Level3, AnonymousObject>> _Join(
                                            outer: IEnumerable<Level3> _ShapedQuery(
                                                queryContext: queryContext, 
                                                shaperCommandContext: SelectExpression: 
                                                    SELECT [l.OneToMany_Optional].[Id], [l.OneToMany_Optional].[Level2_Optional_Id], [l.OneToMany_Optional].[Level2_Required_Id], [l.OneToMany_Optional].[Name], [l.OneToMany_Optional].[OneToMany_Optional_InverseId], [l.OneToMany_Optional].[OneToMany_Optional_Self_InverseId], [l.OneToMany_Optional].[OneToMany_Required_InverseId], [l.OneToMany_Optional].[OneToMany_Required_Self_InverseId], [l.OneToMany_Optional].[OneToOne_Optional_PK_InverseId], [l.OneToMany_Optional].[OneToOne_Optional_SelfId]
                                                    FROM [Level3] AS [l.OneToMany_Optional], 
                                                shaper: BufferedEntityShaper<Level3>), 
                                            inner: IEnumerable<AnonymousObject> _ShapedQuery(
                                                queryContext: queryContext, 
                                                shaperCommandContext: SelectExpression: 
                                                    SELECT 1
                                                    FROM [Level1] AS [l11]
                                                    WHERE [l11].[Id] < 3, 
                                                shaper: TypedProjectionShaper<ValueBufferShaper, ValueBuffer, AnonymousObject>), 
                                            outerKeySelector: (Level3 l.OneToMany_Optional) => Nullable<int> GetValue(
                                                queryContext: queryContext, 
                                                entity: l.OneToMany_Optional, 
                                                property: Level3.OneToMany_Optional_InverseId), 
                                            innerKeySelector: (AnonymousObject _l) => (Nullable<int>)object _l.GetValue(0), 
                                            resultSelector: (Level3 l.OneToMany_Optional | AnonymousObject _l) => TransparentIdentifier<Level3, AnonymousObject> CreateTransparentIdentifier(
                                                outer: l.OneToMany_Optional, 
                                                inner: _l)), 
                                        expression: (TransparentIdentifier<Level3, AnonymousObject> t0) => object t0.Inner.GetValue(0), 
                                        orderingDirection: Asc), 
                                    selector: (TransparentIdentifier<Level3, AnonymousObject> t0) => t0.Outer))
                        }
                    ).Id > 0), 
                queryContext: Unhandled parameter: queryContext))), 
    contextType: TestModels.ComplexNavigationsModel.ComplexNavigationsContext, 
    logger: DiagnosticsLogger<Query>, 
    queryContext: Unhandled parameter: queryContext)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions