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)
query:
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: