diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index 250c95795e1..c8299e02021 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -1185,7 +1185,8 @@ public Expression ApplyCollectionJoin( var outerOrdering = Orderings[i]; if (outerOrdering.Expression.Equals(_identifier[identifierIndex].Column)) { - innerSelectExpression.AppendOrdering(new OrderingExpression(innerSelectExpression._identifier[identifierIndex].Column, ascending: true)); + innerSelectExpression.AppendOrdering(new OrderingExpression( + innerSelectExpression._identifier[identifierIndex].Column, ascending: true)); identifierIndex++; } else @@ -1211,53 +1212,28 @@ public Expression ApplyCollectionJoin( } else { - - var (parentIdentifier, parentIdentifierValueComparers) = GetIdentifierAccessor(_identifier); - var (outerIdentifier, outerIdentifierValueComparers) = GetIdentifierAccessor(_identifier.Concat(_childIdentifiers)); + var parentIdentifierList = _identifier.Except(_childIdentifiers).ToList(); + var (parentIdentifier, parentIdentifierValueComparers) = GetIdentifierAccessor(parentIdentifierList); + var (outerIdentifier, outerIdentifierValueComparers) = GetIdentifierAccessor(_identifier); + var innerClientEval = innerSelectExpression.Projection.Count > 0; innerSelectExpression.ApplyProjection(); - var (selfIdentifier, selfIdentifierValueComparers) = innerSelectExpression.GetIdentifierAccessor(innerSelectExpression._identifier); - if (collectionIndex == 0) { - foreach (var identifier in _identifier) + foreach (var identifier in parentIdentifierList) { AppendOrdering(new OrderingExpression(identifier.Column, ascending: true)); } } - var joinPredicate = TryExtractJoinKey(innerSelectExpression); - var containsOuterReference = new SelectExpressionCorrelationFindingExpressionVisitor(this) - .ContainsOuterReference(innerSelectExpression); - if (containsOuterReference && joinPredicate != null) - { - innerSelectExpression.ApplyPredicate(joinPredicate); - joinPredicate = null; - } - - if (innerSelectExpression.Offset != null - || innerSelectExpression.Limit != null - || innerSelectExpression.IsDistinct - || innerSelectExpression.Predicate != null - || innerSelectExpression.Tables.Count > 1 - || innerSelectExpression.GroupBy.Count > 0) - { - var sqlRemappingVisitor = new SqlRemappingVisitor( - innerSelectExpression.PushdownIntoSubquery(), - (SelectExpression)innerSelectExpression.Tables[0]); - joinPredicate = sqlRemappingVisitor.Remap(joinPredicate); - } - - var joinExpression = joinPredicate == null - ? (TableExpressionBase)new OuterApplyExpression(innerSelectExpression.Tables.Single()) - : new LeftJoinExpression(innerSelectExpression.Tables.Single(), joinPredicate); - _tables.Add(joinExpression); + AddJoin(JoinType.OuterApply, ref innerSelectExpression); foreach (var ordering in innerSelectExpression.Orderings) { AppendOrdering(ordering.Update(MakeNullable(ordering.Expression))); } + var remapper = new ProjectionBindingExpressionRemappingExpressionVisitor(this); var innerProjectionCount = innerSelectExpression.Projection.Count; var indexMap = new int[innerProjectionCount]; for (var i = 0; i < innerProjectionCount; i++) @@ -1265,23 +1241,56 @@ public Expression ApplyCollectionJoin( indexMap[i] = AddToProjection(MakeNullable(innerSelectExpression.Projection[i].Expression)); } - foreach (var identifier in innerSelectExpression._identifier.Concat(innerSelectExpression._childIdentifiers)) + if (innerClientEval) + { + innerShaper = remapper.RemapIndex(innerShaper, indexMap, pendingCollectionOffset: 0); + } + else + { + var mapping = new Dictionary(); + foreach (var projection in innerSelectExpression._projectionMapping) + { + var value = ((ConstantExpression)projection.Value).Value; + object mappedValue = null; + if (value is int index) + { + mappedValue = indexMap[index]; + } + else if (value is IDictionary entityIndexMap) + { + var newEntityIndexMap = new Dictionary(); + foreach (var item in entityIndexMap) + { + newEntityIndexMap[item.Key] = indexMap[item.Value]; + } + mappedValue = newEntityIndexMap; + } + mapping[projection.Key] = mappedValue; + } + + innerShaper = remapper.RemapProjectionMember(innerShaper, mapping, pendingCollectionOffset: 0); + } + + innerShaper = new EntityShaperNullableMarkingExpressionVisitor().Visit(innerShaper); + + var (selfIdentifier, selfIdentifierValueComparers) = GetIdentifierAccessor( + innerSelectExpression._identifier + .Except(innerSelectExpression._childIdentifiers) + .Select(e => (e.Column.MakeNullable(), e.Comparer))); + + foreach (var identifier in innerSelectExpression._identifier) { var updatedColumn = identifier.Column.MakeNullable(); _childIdentifiers.Add((updatedColumn, identifier.Comparer)); AppendOrdering(new OrderingExpression(updatedColumn, ascending: true)); } - // Inner should not have pendingCollection since we apply them first. - // Shaper should not have CollectionShaperExpression as any collection would get converted to RelationalCollectionShaperExpression. - var shaperRemapper = new ShaperRemappingExpressionVisitor(this, innerSelectExpression, indexMap, pendingCollectionOffset: 0); - innerShaper = shaperRemapper.Visit(innerShaper); - selfIdentifier = shaperRemapper.Visit(selfIdentifier); - - return new RelationalCollectionShaperExpression( + var result = new RelationalCollectionShaperExpression( collectionId, parentIdentifier, outerIdentifier, selfIdentifier, parentIdentifierValueComparers, outerIdentifierValueComparers, selfIdentifierValueComparers, innerShaper, navigation, elementType); + + return result; } } @@ -1764,68 +1773,6 @@ private ProjectionBindingExpression CreateNewBinding(object binding, Type type) }; } - private sealed class ShaperRemappingExpressionVisitor : ExpressionVisitor - { - private readonly SelectExpression _queryExpression; - private readonly SelectExpression _innerSelectExpression; - private readonly int[] _indexMap; - private readonly int _pendingCollectionOffset; - - public ShaperRemappingExpressionVisitor( - SelectExpression queryExpression, SelectExpression innerSelectExpression, int[] indexMap, int pendingCollectionOffset) - { - _queryExpression = queryExpression; - _innerSelectExpression = innerSelectExpression; - _pendingCollectionOffset = pendingCollectionOffset; - _indexMap = indexMap; - } - - protected override Expression VisitExtension(Expression extensionExpression) - { - Check.NotNull(extensionExpression, nameof(extensionExpression)); - - switch (extensionExpression) - { - case ProjectionBindingExpression projectionBindingExpression: - return new ProjectionBindingExpression( - _queryExpression, _indexMap[(int)GetProjectionIndex(projectionBindingExpression)], projectionBindingExpression.Type); - - case EntityShaperExpression entityShaperExpression: - var oldIndexMap = (IDictionary)GetProjectionIndex( - (ProjectionBindingExpression)entityShaperExpression.ValueBufferExpression); - var indexMap = new Dictionary(); - foreach (var keyValuePair in oldIndexMap) - { - indexMap[keyValuePair.Key] = _indexMap[keyValuePair.Value]; - } - - return new RelationalEntityShaperExpression( - entityShaperExpression.EntityType, - new ProjectionBindingExpression(_queryExpression, indexMap), - nullable: true); - - case CollectionShaperExpression collectionShaperExpression: - var collectionIndex = (int)GetProjectionIndex((ProjectionBindingExpression)collectionShaperExpression.Projection); - - return collectionShaperExpression.Update( - new ProjectionBindingExpression(_queryExpression, collectionIndex + _pendingCollectionOffset, typeof(object)), - collectionShaperExpression.InnerShaper); - - default: - return base.VisitExtension(extensionExpression); - } - } - - private object GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression) - { - return projectionBindingExpression.ProjectionMember != null - ? ((ConstantExpression)_innerSelectExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember)).Value - : (projectionBindingExpression.Index != null - ? (object)projectionBindingExpression.Index - : projectionBindingExpression.IndexMap); - } - } - private void AddJoin( JoinType joinType, ref SelectExpression innerSelectExpression, @@ -1848,6 +1795,7 @@ private void AddJoin( if (containsOuterReference) { innerSelectExpression.ApplyPredicate(joinPredicate); + joinPredicate = null; if (limit != null) { innerSelectExpression.ApplyLimit(limit); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index 897559b3d3e..8d36b98cc4a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -4354,7 +4354,7 @@ public override async Task Select_subquery_single_nested_subquery(bool async) await base.Select_subquery_single_nested_subquery(async); AssertSql( - @"SELECT [t0].[c], [l].[Id], [t0].[Id], [l1].[Id] + @"SELECT [t0].[c], [l].[Id], [t0].[Id], [t1].[Id] FROM [LevelOne] AS [l] LEFT JOIN ( SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse2Id] @@ -4364,8 +4364,11 @@ FROM [LevelTwo] AS [l0] ) AS [t] WHERE [t].[row] <= 1 ) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] -LEFT JOIN [LevelThree] AS [l1] ON [t0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] -ORDER BY [l].[Id], [t0].[Id], [l1].[Id]"); +LEFT JOIN ( + SELECT [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id] + FROM [LevelThree] AS [l1] +) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [t0].[Id], [t1].[Id]"); } public override async Task Select_subquery_single_nested_subquery2(bool async) @@ -4373,10 +4376,10 @@ public override async Task Select_subquery_single_nested_subquery2(bool async) await base.Select_subquery_single_nested_subquery2(async); AssertSql( - @"SELECT [l].[Id], [t1].[c], [t1].[Id], [t1].[Id0], [t1].[Id1] + @"SELECT [l].[Id], [t2].[c], [t2].[Id], [t2].[Id0], [t2].[Id1] FROM [LevelOne] AS [l] LEFT JOIN ( - SELECT [t0].[c], [l0].[Id], [t0].[Id] AS [Id0], [l2].[Id] AS [Id1], [l0].[OneToMany_Optional_Inverse2Id] + SELECT [t0].[c], [l0].[Id], [t0].[Id] AS [Id0], [t1].[Id] AS [Id1], [l0].[OneToMany_Optional_Inverse2Id] FROM [LevelTwo] AS [l0] LEFT JOIN ( SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse3Id] @@ -4386,9 +4389,12 @@ FROM [LevelThree] AS [l1] ) AS [t] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] - LEFT JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Optional_Inverse4Id] -) AS [t1] ON [l].[Id] = [t1].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [t1].[Id], [t1].[Id0], [t1].[Id1]"); + LEFT JOIN ( + SELECT [l2].[Id], [l2].[OneToMany_Optional_Inverse4Id] + FROM [LevelFour] AS [l2] + ) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Optional_Inverse4Id] +) AS [t2] ON [l].[Id] = [t2].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t2].[Id], [t2].[Id0], [t2].[Id1]"); } public override async Task SelectMany_with_outside_reference_to_joined_table_correctly_translated_to_apply(bool async) @@ -4501,10 +4507,13 @@ public override async Task Filtered_include_OrderBy(bool async) await base.Filtered_include_OrderBy(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [l0].[Name], [l0].[Id]"); +LEFT JOIN ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Name], [t].[Id]"); } public override async Task Filtered_ThenInclude_OrderBy(bool async) @@ -4512,14 +4521,17 @@ public override async Task Filtered_ThenInclude_OrderBy(bool async) await base.Filtered_ThenInclude_OrderBy(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id], [t].[Id0], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name0], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id], [t0].[Id0], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name0], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] FROM [LevelOne] AS [l] LEFT JOIN ( - SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [l1].[Id] AS [Id0], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name] AS [Name0], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t].[Id] AS [Id0], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name] AS [Name0], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] FROM [LevelTwo] AS [l0] - LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] -) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [t].[Id], [t].[Name0], [t].[Id0]"); + LEFT JOIN ( + SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] + FROM [LevelThree] AS [l1] + ) AS [t] ON [l0].[Id] = [t].[OneToMany_Optional_Inverse3Id] +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id], [t0].[Name0], [t0].[Id0]"); } public override async Task Filtered_include_ThenInclude_OrderBy(bool async) @@ -4527,14 +4539,17 @@ public override async Task Filtered_include_ThenInclude_OrderBy(bool async) await base.Filtered_include_ThenInclude_OrderBy(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id], [t].[Id0], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name0], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id], [t0].[Id0], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name0], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] FROM [LevelOne] AS [l] LEFT JOIN ( - SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [l1].[Id] AS [Id0], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name] AS [Name0], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t].[Id] AS [Id0], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name] AS [Name0], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] FROM [LevelTwo] AS [l0] - LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] -) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [t].[Name], [t].[Id], [t].[Name0] DESC, [t].[Id0]"); + LEFT JOIN ( + SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] + FROM [LevelThree] AS [l1] + ) AS [t] ON [l0].[Id] = [t].[OneToMany_Optional_Inverse3Id] +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Name], [t0].[Id], [t0].[Name0] DESC, [t0].[Id0]"); } public override async Task Filtered_include_basic_OrderBy_Take(bool async) @@ -4542,15 +4557,17 @@ public override async Task Filtered_include_basic_OrderBy_Take(bool async) await base.Filtered_include_basic_OrderBy_Take(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] - ORDER BY [l0].[Name] -) AS [t] -ORDER BY [l].[Id], [t].[Name], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Name]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_basic_OrderBy_Skip(bool async) @@ -4558,16 +4575,17 @@ public override async Task Filtered_include_basic_OrderBy_Skip(bool async) await base.Filtered_include_basic_OrderBy_Skip(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] - ORDER BY [l0].[Name] - OFFSET 1 ROWS -) AS [t] -ORDER BY [l].[Id], [t].[Name], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Name]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t] + WHERE 1 < [t].[row] +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_basic_OrderBy_Skip_Take(bool async) @@ -4575,16 +4593,17 @@ public override async Task Filtered_include_basic_OrderBy_Skip_Take(bool async) await base.Filtered_include_basic_OrderBy_Skip_Take(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] - ORDER BY [l0].[Name] - OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY -) AS [t] -ORDER BY [l].[Id], [t].[Name], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Name]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t] + WHERE (1 < [t].[row]) AND ([t].[row] <= 4) +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override void Filtered_include_Skip_without_OrderBy() @@ -4592,16 +4611,17 @@ public override void Filtered_include_Skip_without_OrderBy() base.Filtered_include_Skip_without_OrderBy(); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] - ORDER BY (SELECT 1) - OFFSET 1 ROWS -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t] + WHERE 1 < [t].[row] +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override void Filtered_include_Take_without_OrderBy() @@ -4609,14 +4629,17 @@ public override void Filtered_include_Take_without_OrderBy() base.Filtered_include_Take_without_OrderBy(); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(1) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t] + WHERE [t].[row] <= 1 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_on_ThenInclude(bool async) @@ -4624,17 +4647,19 @@ public override async Task Filtered_include_on_ThenInclude(bool async) await base.Filtered_include_on_ThenInclude(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t].[Id], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t0].[Id], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -OUTER APPLY ( - SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] - FROM [LevelThree] AS [l1] - WHERE ([l0].[Id] IS NOT NULL AND ([l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id])) AND (([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL) - ORDER BY [l1].[Name] - OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY -) AS [t] -ORDER BY [l].[Id], [l0].[Id], [t].[Name], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + FROM ( + SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Optional_Inverse3Id] ORDER BY [l1].[Name]) AS [row] + FROM [LevelThree] AS [l1] + WHERE ([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL + ) AS [t] + WHERE (1 < [t].[row]) AND ([t].[row] <= 4) +) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [t0].[Id]"); } public override async Task Filtered_include_after_reference_navigation(bool async) @@ -4642,17 +4667,19 @@ public override async Task Filtered_include_after_reference_navigation(bool asyn await base.Filtered_include_after_reference_navigation(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t].[Id], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], [t0].[Id], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] -OUTER APPLY ( - SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] - FROM [LevelThree] AS [l1] - WHERE ([l0].[Id] IS NOT NULL AND ([l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id])) AND (([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL) - ORDER BY [l1].[Name] - OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY -) AS [t] -ORDER BY [l].[Id], [l0].[Id], [t].[Name], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Level2_Optional_Id], [t].[Level2_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse3Id], [t].[OneToMany_Optional_Self_Inverse3Id], [t].[OneToMany_Required_Inverse3Id], [t].[OneToMany_Required_Self_Inverse3Id], [t].[OneToOne_Optional_PK_Inverse3Id], [t].[OneToOne_Optional_Self3Id] + FROM ( + SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Optional_Inverse3Id] ORDER BY [l1].[Name]) AS [row] + FROM [LevelThree] AS [l1] + WHERE ([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL + ) AS [t] + WHERE (1 < [t].[row]) AND ([t].[row] <= 4) +) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [t0].[Id]"); } public override async Task Filtered_include_after_different_filtered_include_same_level(bool async) @@ -4660,22 +4687,27 @@ public override async Task Filtered_include_after_different_filtered_include_sam await base.Filtered_include_after_different_filtered_include_same_level(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id], [t2].[Id], [t2].[Date], [t2].[Level1_Optional_Id], [t2].[Level1_Required_Id], [t2].[Name], [t2].[OneToMany_Optional_Inverse2Id], [t2].[OneToMany_Optional_Self_Inverse2Id], [t2].[OneToMany_Required_Inverse2Id], [t2].[OneToMany_Required_Self_Inverse2Id], [t2].[OneToOne_Optional_PK_Inverse2Id], [t2].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL) - ORDER BY [l0].[Name] -) AS [t] -OUTER APPLY ( - SELECT [l1].[Id], [l1].[Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse2Id], [l1].[OneToMany_Optional_Self_Inverse2Id], [l1].[OneToMany_Required_Inverse2Id], [l1].[OneToMany_Required_Self_Inverse2Id], [l1].[OneToOne_Optional_PK_Inverse2Id], [l1].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l1] - WHERE ([l].[Id] = [l1].[OneToMany_Required_Inverse2Id]) AND (([l1].[Name] <> N'Bar') OR [l1].[Name] IS NULL) - ORDER BY [l1].[Name] DESC - OFFSET 1 ROWS -) AS [t0] -ORDER BY [l].[Id], [t].[Name], [t].[Id], [t0].[Name] DESC, [t0].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Name]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +LEFT JOIN ( + SELECT [t1].[Id], [t1].[Date], [t1].[Level1_Optional_Id], [t1].[Level1_Required_Id], [t1].[Name], [t1].[OneToMany_Optional_Inverse2Id], [t1].[OneToMany_Optional_Self_Inverse2Id], [t1].[OneToMany_Required_Inverse2Id], [t1].[OneToMany_Required_Self_Inverse2Id], [t1].[OneToOne_Optional_PK_Inverse2Id], [t1].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l1].[Id], [l1].[Date], [l1].[Level1_Optional_Id], [l1].[Level1_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse2Id], [l1].[OneToMany_Optional_Self_Inverse2Id], [l1].[OneToMany_Required_Inverse2Id], [l1].[OneToMany_Required_Self_Inverse2Id], [l1].[OneToOne_Optional_PK_Inverse2Id], [l1].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Required_Inverse2Id] ORDER BY [l1].[Name] DESC) AS [row] + FROM [LevelTwo] AS [l1] + WHERE ([l1].[Name] <> N'Bar') OR [l1].[Name] IS NULL + ) AS [t1] + WHERE 1 < [t1].[row] +) AS [t2] ON [l].[Id] = [t2].[OneToMany_Required_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id], [t2].[Id]"); } public override async Task Filtered_include_after_different_filtered_include_different_level(bool async) @@ -4683,25 +4715,27 @@ public override async Task Filtered_include_after_different_filtered_include_dif await base.Filtered_include_after_different_filtered_include_different_level(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t1].[Id], [t1].[Date], [t1].[Level1_Optional_Id], [t1].[Level1_Required_Id], [t1].[Name], [t1].[OneToMany_Optional_Inverse2Id], [t1].[OneToMany_Optional_Self_Inverse2Id], [t1].[OneToMany_Required_Inverse2Id], [t1].[OneToMany_Required_Self_Inverse2Id], [t1].[OneToOne_Optional_PK_Inverse2Id], [t1].[OneToOne_Optional_Self2Id], [t1].[Id0], [t1].[Level2_Optional_Id], [t1].[Level2_Required_Id], [t1].[Name0], [t1].[OneToMany_Optional_Inverse3Id], [t1].[OneToMany_Optional_Self_Inverse3Id], [t1].[OneToMany_Required_Inverse3Id], [t1].[OneToMany_Required_Self_Inverse3Id], [t1].[OneToOne_Optional_PK_Inverse3Id], [t1].[OneToOne_Optional_Self3Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t2].[Id], [t2].[Date], [t2].[Level1_Optional_Id], [t2].[Level1_Required_Id], [t2].[Name], [t2].[OneToMany_Optional_Inverse2Id], [t2].[OneToMany_Optional_Self_Inverse2Id], [t2].[OneToMany_Required_Inverse2Id], [t2].[OneToMany_Required_Self_Inverse2Id], [t2].[OneToOne_Optional_PK_Inverse2Id], [t2].[OneToOne_Optional_Self2Id], [t2].[Id0], [t2].[Level2_Optional_Id], [t2].[Level2_Required_Id], [t2].[Name0], [t2].[OneToMany_Optional_Inverse3Id], [t2].[OneToMany_Optional_Self_Inverse3Id], [t2].[OneToMany_Required_Inverse3Id], [t2].[OneToMany_Required_Self_Inverse3Id], [t2].[OneToOne_Optional_PK_Inverse3Id], [t2].[OneToOne_Optional_Self3Id] FROM [LevelOne] AS [l] OUTER APPLY ( - SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id], [t0].[Id] AS [Id0], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name] AS [Name0], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id], [t1].[Id] AS [Id0], [t1].[Level2_Optional_Id], [t1].[Level2_Required_Id], [t1].[Name] AS [Name0], [t1].[OneToMany_Optional_Inverse3Id], [t1].[OneToMany_Optional_Self_Inverse3Id], [t1].[OneToMany_Required_Inverse3Id], [t1].[OneToMany_Required_Self_Inverse3Id], [t1].[OneToOne_Optional_PK_Inverse3Id], [t1].[OneToOne_Optional_Self3Id] FROM ( SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] FROM [LevelTwo] AS [l0] WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL) ORDER BY [l0].[Name] ) AS [t] - OUTER APPLY ( - SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id] - FROM [LevelThree] AS [l1] - WHERE ([t].[Id] = [l1].[OneToMany_Required_Inverse3Id]) AND (([l1].[Name] <> N'Bar') OR [l1].[Name] IS NULL) - ORDER BY [l1].[Name] DESC - OFFSET 1 ROWS - ) AS [t0] -) AS [t1] -ORDER BY [l].[Id], [t1].[Name], [t1].[Id], [t1].[Name0] DESC, [t1].[Id0]"); + LEFT JOIN ( + SELECT [t0].[Id], [t0].[Level2_Optional_Id], [t0].[Level2_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse3Id], [t0].[OneToMany_Optional_Self_Inverse3Id], [t0].[OneToMany_Required_Inverse3Id], [t0].[OneToMany_Required_Self_Inverse3Id], [t0].[OneToOne_Optional_PK_Inverse3Id], [t0].[OneToOne_Optional_Self3Id] + FROM ( + SELECT [l1].[Id], [l1].[Level2_Optional_Id], [l1].[Level2_Required_Id], [l1].[Name], [l1].[OneToMany_Optional_Inverse3Id], [l1].[OneToMany_Optional_Self_Inverse3Id], [l1].[OneToMany_Required_Inverse3Id], [l1].[OneToMany_Required_Self_Inverse3Id], [l1].[OneToOne_Optional_PK_Inverse3Id], [l1].[OneToOne_Optional_Self3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Required_Inverse3Id] ORDER BY [l1].[Name] DESC) AS [row] + FROM [LevelThree] AS [l1] + WHERE ([l1].[Name] <> N'Bar') OR [l1].[Name] IS NULL + ) AS [t0] + WHERE 1 < [t0].[row] + ) AS [t1] ON [t].[Id] = [t1].[OneToMany_Required_Inverse3Id] +) AS [t2] +ORDER BY [l].[Id], [t2].[Name], [t2].[Id], [t2].[Id0]"); } public override async Task Filtered_include_same_filter_set_on_same_navigation_twice(bool async) @@ -4709,15 +4743,18 @@ public override async Task Filtered_include_same_filter_set_on_same_navigation_t await base.Filtered_include_same_filter_set_on_same_navigation_twice(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(2) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL) - ORDER BY [l0].[Id] DESC -) AS [t] -ORDER BY [l].[Id], [t].[Id] DESC"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id] DESC) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL + ) AS [t] + WHERE [t].[row] <= 2 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_same_filter_set_on_same_navigation_twice_followed_by_ThenIncludes(bool async) @@ -4767,15 +4804,18 @@ public override async Task Filtered_include_and_non_filtered_include_on_same_nav await base.Filtered_include_and_non_filtered_include_on_same_navigation1(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL) - ORDER BY [l0].[Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_and_non_filtered_include_on_same_navigation2(bool async) @@ -4783,15 +4823,18 @@ public override async Task Filtered_include_and_non_filtered_include_on_same_nav await base.Filtered_include_and_non_filtered_include_on_same_navigation2(async); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL) - ORDER BY [l0].[Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override async Task Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(bool async) @@ -4876,15 +4919,18 @@ public override void Filtered_include_variable_used_inside_filter() AssertSql( @"@__prm_0='Foo' (Size = 4000) -SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] +SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> @__prm_0) OR [l0].[Name] IS NULL) - ORDER BY [l0].[Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ([l0].[Name] <> @__prm_0) OR [l0].[Name] IS NULL + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override void Filtered_include_context_accessed_inside_filter() @@ -4897,15 +4943,18 @@ public override void Filtered_include_context_accessed_inside_filter() // @"@__p_0='True' -SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] +SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (@__p_0 = CAST(1 AS bit)) - ORDER BY [l0].[Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE @__p_0 = CAST(1 AS bit) + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override void Filtered_include_context_accessed_inside_filter_correlated() @@ -4913,18 +4962,21 @@ public override void Filtered_include_context_accessed_inside_filter_correlated( base.Filtered_include_context_accessed_inside_filter_correlated(); AssertSql( - @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id], [t0].[Id], [t0].[Date], [t0].[Level1_Optional_Id], [t0].[Level1_Required_Id], [t0].[Name], [t0].[OneToMany_Optional_Inverse2Id], [t0].[OneToMany_Optional_Self_Inverse2Id], [t0].[OneToMany_Required_Inverse2Id], [t0].[OneToMany_Required_Self_Inverse2Id], [t0].[OneToOne_Optional_PK_Inverse2Id], [t0].[OneToOne_Optional_Self2Id] FROM [LevelOne] AS [l] -OUTER APPLY ( - SELECT TOP(3) [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id] - FROM [LevelTwo] AS [l0] - WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (( - SELECT COUNT(*) - FROM [LevelOne] AS [l1] - WHERE [l1].[Id] <> [l0].[Id]) > 1) - ORDER BY [l0].[Id] -) AS [t] -ORDER BY [l].[Id], [t].[Id]"); +LEFT JOIN ( + SELECT [t].[Id], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id], [t].[OneToMany_Optional_Self_Inverse2Id], [t].[OneToMany_Required_Inverse2Id], [t].[OneToMany_Required_Self_Inverse2Id], [t].[OneToOne_Optional_PK_Inverse2Id], [t].[OneToOne_Optional_Self2Id] + FROM ( + SELECT [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + WHERE ( + SELECT COUNT(*) + FROM [LevelOne] AS [l1] + WHERE [l1].[Id] <> [l0].[Id]) > 1 + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]"); } public override void Filtered_include_outer_parameter_used_inside_filter() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 090878c8e40..fb440bc0d76 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -3816,16 +3816,19 @@ public override async Task Correlated_collections_different_collections_projecte await base.Correlated_collections_different_collections_projected(async); AssertSql( - @"SELECT [g].[Nickname], [g].[SquadId], [t].[Name], [t].[IsAutomatic], [t].[Id], [g0].[Nickname], [g0].[Rank], [g0].[SquadId] + @"SELECT [g].[Nickname], [g].[SquadId], [t].[Name], [t].[IsAutomatic], [t].[Id], [t0].[Nickname], [t0].[Rank], [t0].[SquadId] FROM [Gears] AS [g] LEFT JOIN ( SELECT [w].[Name], [w].[IsAutomatic], [w].[Id], [w].[OwnerFullName] FROM [Weapons] AS [w] WHERE [w].[IsAutomatic] = CAST(1 AS bit) ) AS [t] ON [g].[FullName] = [t].[OwnerFullName] -LEFT JOIN [Gears] AS [g0] ON ([g].[Nickname] = [g0].[LeaderNickname]) AND ([g].[SquadId] = [g0].[LeaderSquadId]) +LEFT JOIN ( + SELECT [g0].[Nickname], [g0].[Rank], [g0].[SquadId], [g0].[FullName], [g0].[LeaderNickname], [g0].[LeaderSquadId] + FROM [Gears] AS [g0] +) AS [t0] ON ([g].[Nickname] = [t0].[LeaderNickname]) AND ([g].[SquadId] = [t0].[LeaderSquadId]) WHERE [g].[Discriminator] = N'Officer' -ORDER BY [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [g0].[FullName], [g0].[Nickname], [g0].[SquadId]"); +ORDER BY [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [t0].[FullName], [t0].[Nickname], [t0].[SquadId]"); } public override async Task Multiple_orderby_with_navigation_expansion_on_one_of_the_order_bys(bool async) @@ -3916,34 +3919,37 @@ public override async Task Correlated_collections_multiple_nested_complex_collec await base.Correlated_collections_multiple_nested_complex_collections(async); AssertSql( - @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [g0].[Nickname], [g0].[SquadId], [t1].[FullName], [t1].[Nickname], [t1].[SquadId], [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Name], [t1].[IsAutomatic], [t1].[Id1], [t1].[Nickname00], [t1].[HasSoulPatch], [t1].[SquadId00], [t2].[Id], [t2].[AmmunitionType], [t2].[IsAutomatic], [t2].[Name], [t2].[OwnerFullName], [t2].[SynergyWithId], [t2].[Nickname], [t2].[SquadId] + @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [g0].[Nickname], [g0].[SquadId], [t2].[FullName], [t2].[Nickname], [t2].[SquadId], [t2].[Id], [t2].[Nickname0], [t2].[SquadId0], [t2].[Id0], [t2].[Name], [t2].[IsAutomatic], [t2].[Id1], [t2].[Nickname00], [t2].[HasSoulPatch], [t2].[SquadId00], [t3].[Id], [t3].[AmmunitionType], [t3].[IsAutomatic], [t3].[Name], [t3].[OwnerFullName], [t3].[SynergyWithId], [t3].[Nickname], [t3].[SquadId] FROM [Gears] AS [g] LEFT JOIN [Tags] AS [t] ON ([g].[Nickname] = [t].[GearNickName]) AND ([g].[SquadId] = [t].[GearSquadId]) LEFT JOIN [Gears] AS [g0] ON ([t].[GearNickName] = [g0].[Nickname]) AND ([t].[GearSquadId] = [g0].[SquadId]) LEFT JOIN ( - SELECT [g1].[FullName], [g1].[Nickname], [g1].[SquadId], [t0].[Id], [t0].[Nickname] AS [Nickname0], [t0].[SquadId] AS [SquadId0], [t0].[Id0], [t0].[Name], [t0].[IsAutomatic], [t0].[Id1], [t0].[Nickname0] AS [Nickname00], [t0].[HasSoulPatch], [t0].[SquadId0] AS [SquadId00], [g1].[Rank], [t0].[IsAutomatic0], [g1].[LeaderNickname], [g1].[LeaderSquadId] + SELECT [g1].[FullName], [g1].[Nickname], [g1].[SquadId], [t1].[Id], [t1].[Nickname] AS [Nickname0], [t1].[SquadId] AS [SquadId0], [t1].[Id0], [t1].[Name], [t1].[IsAutomatic], [t1].[Id1], [t1].[Nickname0] AS [Nickname00], [t1].[HasSoulPatch], [t1].[SquadId0] AS [SquadId00], [g1].[Rank], [t1].[IsAutomatic0], [g1].[LeaderNickname], [g1].[LeaderSquadId] FROM [Gears] AS [g1] LEFT JOIN ( - SELECT [w].[Id], [g2].[Nickname], [g2].[SquadId], [s].[Id] AS [Id0], [w0].[Name], [w0].[IsAutomatic], [w0].[Id] AS [Id1], [g3].[Nickname] AS [Nickname0], [g3].[HasSoulPatch], [g3].[SquadId] AS [SquadId0], [w].[IsAutomatic] AS [IsAutomatic0], [w].[OwnerFullName] + SELECT [w].[Id], [g2].[Nickname], [g2].[SquadId], [s].[Id] AS [Id0], [w0].[Name], [w0].[IsAutomatic], [w0].[Id] AS [Id1], [t0].[Nickname] AS [Nickname0], [t0].[HasSoulPatch], [t0].[SquadId] AS [SquadId0], [w].[IsAutomatic] AS [IsAutomatic0], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN [Gears] AS [g2] ON [w].[OwnerFullName] = [g2].[FullName] LEFT JOIN [Squads] AS [s] ON [g2].[SquadId] = [s].[Id] LEFT JOIN [Weapons] AS [w0] ON [g2].[FullName] = [w0].[OwnerFullName] - LEFT JOIN [Gears] AS [g3] ON [s].[Id] = [g3].[SquadId] + LEFT JOIN ( + SELECT [g3].[Nickname], [g3].[HasSoulPatch], [g3].[SquadId] + FROM [Gears] AS [g3] + ) AS [t0] ON [s].[Id] = [t0].[SquadId] WHERE ([w].[Name] <> N'Bar') OR [w].[Name] IS NULL - ) AS [t0] ON [g1].[FullName] = [t0].[OwnerFullName] + ) AS [t1] ON [g1].[FullName] = [t1].[OwnerFullName] WHERE [g1].[FullName] <> N'Foo' -) AS [t1] ON ([g].[Nickname] = [t1].[LeaderNickname]) AND ([g].[SquadId] = [t1].[LeaderSquadId]) +) AS [t2] ON ([g].[Nickname] = [t2].[LeaderNickname]) AND ([g].[SquadId] = [t2].[LeaderSquadId]) LEFT JOIN ( SELECT [w1].[Id], [w1].[AmmunitionType], [w1].[IsAutomatic], [w1].[Name], [w1].[OwnerFullName], [w1].[SynergyWithId], [g4].[Nickname], [g4].[SquadId] FROM [Weapons] AS [w1] LEFT JOIN [Gears] AS [g4] ON [w1].[OwnerFullName] = [g4].[FullName] -) AS [t2] ON [g0].[FullName] = [t2].[OwnerFullName] +) AS [t3] ON [g0].[FullName] = [t3].[OwnerFullName] WHERE ([g].[Discriminator] = N'Officer') AND EXISTS ( SELECT 1 FROM [Gears] AS [g5] WHERE ([g].[Nickname] = [g5].[LeaderNickname]) AND ([g].[SquadId] = [g5].[LeaderSquadId])) -ORDER BY [g].[HasSoulPatch] DESC, [t].[Note], [g].[Nickname], [g].[SquadId], [t].[Id], [g0].[Nickname], [g0].[SquadId], [t1].[Rank], [t1].[Nickname], [t1].[SquadId], [t1].[IsAutomatic0], [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Id1], [t1].[Nickname00], [t1].[SquadId00], [t2].[IsAutomatic], [t2].[Nickname] DESC, [t2].[Id], [t2].[SquadId]"); +ORDER BY [g].[HasSoulPatch] DESC, [t].[Note], [g].[Nickname], [g].[SquadId], [t].[Id], [g0].[Nickname], [g0].[SquadId], [t2].[Rank], [t2].[Nickname], [t2].[SquadId], [t2].[IsAutomatic0], [t2].[Id], [t2].[Nickname0], [t2].[SquadId0], [t2].[Id0], [t2].[Id1], [t2].[Nickname00], [t2].[SquadId00], [t3].[IsAutomatic], [t3].[Nickname] DESC, [t3].[Id], [t3].[SquadId]"); } public override async Task Correlated_collections_inner_subquery_selector_references_outer_qsre(bool async) @@ -4209,16 +4215,19 @@ public override async Task Correlated_collections_complex_scenario1(bool async) await base.Correlated_collections_complex_scenario1(async); AssertSql( - @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [t].[Nickname], [t].[SquadId], [t].[Id0], [t].[Nickname0], [t].[HasSoulPatch], [t].[SquadId0] + @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t0].[Id], [t0].[Nickname], [t0].[SquadId], [t0].[Id0], [t0].[Nickname0], [t0].[HasSoulPatch], [t0].[SquadId0] FROM [Gears] AS [g] LEFT JOIN ( - SELECT [w].[Id], [g0].[Nickname], [g0].[SquadId], [s].[Id] AS [Id0], [g1].[Nickname] AS [Nickname0], [g1].[HasSoulPatch], [g1].[SquadId] AS [SquadId0], [w].[OwnerFullName] + SELECT [w].[Id], [g0].[Nickname], [g0].[SquadId], [s].[Id] AS [Id0], [t].[Nickname] AS [Nickname0], [t].[HasSoulPatch], [t].[SquadId] AS [SquadId0], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN [Gears] AS [g0] ON [w].[OwnerFullName] = [g0].[FullName] LEFT JOIN [Squads] AS [s] ON [g0].[SquadId] = [s].[Id] - LEFT JOIN [Gears] AS [g1] ON [s].[Id] = [g1].[SquadId] -) AS [t] ON [g].[FullName] = [t].[OwnerFullName] -ORDER BY [g].[Nickname], [g].[SquadId], [t].[Id], [t].[Nickname], [t].[SquadId], [t].[Id0], [t].[Nickname0], [t].[SquadId0]"); + LEFT JOIN ( + SELECT [g1].[Nickname], [g1].[HasSoulPatch], [g1].[SquadId] + FROM [Gears] AS [g1] + ) AS [t] ON [s].[Id] = [t].[SquadId] +) AS [t0] ON [g].[FullName] = [t0].[OwnerFullName] +ORDER BY [g].[Nickname], [g].[SquadId], [t0].[Id], [t0].[Nickname], [t0].[SquadId], [t0].[Id0], [t0].[Nickname0], [t0].[SquadId0]"); } public override async Task Correlated_collections_complex_scenario2(bool async) @@ -4226,21 +4235,24 @@ public override async Task Correlated_collections_complex_scenario2(bool async) await base.Correlated_collections_complex_scenario2(async); AssertSql( - @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t0].[FullName], [t0].[Nickname], [t0].[SquadId], [t0].[Id], [t0].[Nickname0], [t0].[SquadId0], [t0].[Id0], [t0].[Nickname00], [t0].[HasSoulPatch], [t0].[SquadId00] + @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t1].[FullName], [t1].[Nickname], [t1].[SquadId], [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Nickname00], [t1].[HasSoulPatch], [t1].[SquadId00] FROM [Gears] AS [g] LEFT JOIN ( - SELECT [g0].[FullName], [g0].[Nickname], [g0].[SquadId], [t].[Id], [t].[Nickname] AS [Nickname0], [t].[SquadId] AS [SquadId0], [t].[Id0], [t].[Nickname0] AS [Nickname00], [t].[HasSoulPatch], [t].[SquadId0] AS [SquadId00], [g0].[LeaderNickname], [g0].[LeaderSquadId] + SELECT [g0].[FullName], [g0].[Nickname], [g0].[SquadId], [t0].[Id], [t0].[Nickname] AS [Nickname0], [t0].[SquadId] AS [SquadId0], [t0].[Id0], [t0].[Nickname0] AS [Nickname00], [t0].[HasSoulPatch], [t0].[SquadId0] AS [SquadId00], [g0].[LeaderNickname], [g0].[LeaderSquadId] FROM [Gears] AS [g0] LEFT JOIN ( - SELECT [w].[Id], [g1].[Nickname], [g1].[SquadId], [s].[Id] AS [Id0], [g2].[Nickname] AS [Nickname0], [g2].[HasSoulPatch], [g2].[SquadId] AS [SquadId0], [w].[OwnerFullName] + SELECT [w].[Id], [g1].[Nickname], [g1].[SquadId], [s].[Id] AS [Id0], [t].[Nickname] AS [Nickname0], [t].[HasSoulPatch], [t].[SquadId] AS [SquadId0], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN [Gears] AS [g1] ON [w].[OwnerFullName] = [g1].[FullName] LEFT JOIN [Squads] AS [s] ON [g1].[SquadId] = [s].[Id] - LEFT JOIN [Gears] AS [g2] ON [s].[Id] = [g2].[SquadId] - ) AS [t] ON [g0].[FullName] = [t].[OwnerFullName] -) AS [t0] ON ([g].[Nickname] = [t0].[LeaderNickname]) AND ([g].[SquadId] = [t0].[LeaderSquadId]) + LEFT JOIN ( + SELECT [g2].[Nickname], [g2].[HasSoulPatch], [g2].[SquadId] + FROM [Gears] AS [g2] + ) AS [t] ON [s].[Id] = [t].[SquadId] + ) AS [t0] ON [g0].[FullName] = [t0].[OwnerFullName] +) AS [t1] ON ([g].[Nickname] = [t1].[LeaderNickname]) AND ([g].[SquadId] = [t1].[LeaderSquadId]) WHERE [g].[Discriminator] = N'Officer' -ORDER BY [g].[Nickname], [g].[SquadId], [t0].[Nickname], [t0].[SquadId], [t0].[Id], [t0].[Nickname0], [t0].[SquadId0], [t0].[Id0], [t0].[Nickname00], [t0].[SquadId00]"); +ORDER BY [g].[Nickname], [g].[SquadId], [t1].[Nickname], [t1].[SquadId], [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Nickname00], [t1].[SquadId00]"); } public override async Task Correlated_collections_with_funky_orderby_complex_scenario1(bool async) @@ -4248,16 +4260,19 @@ public override async Task Correlated_collections_with_funky_orderby_complex_sce await base.Correlated_collections_with_funky_orderby_complex_scenario1(async); AssertSql( - @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[Id], [t].[Nickname], [t].[SquadId], [t].[Id0], [t].[Nickname0], [t].[HasSoulPatch], [t].[SquadId0] + @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t0].[Id], [t0].[Nickname], [t0].[SquadId], [t0].[Id0], [t0].[Nickname0], [t0].[HasSoulPatch], [t0].[SquadId0] FROM [Gears] AS [g] LEFT JOIN ( - SELECT [w].[Id], [g0].[Nickname], [g0].[SquadId], [s].[Id] AS [Id0], [g1].[Nickname] AS [Nickname0], [g1].[HasSoulPatch], [g1].[SquadId] AS [SquadId0], [w].[OwnerFullName] + SELECT [w].[Id], [g0].[Nickname], [g0].[SquadId], [s].[Id] AS [Id0], [t].[Nickname] AS [Nickname0], [t].[HasSoulPatch], [t].[SquadId] AS [SquadId0], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN [Gears] AS [g0] ON [w].[OwnerFullName] = [g0].[FullName] LEFT JOIN [Squads] AS [s] ON [g0].[SquadId] = [s].[Id] - LEFT JOIN [Gears] AS [g1] ON [s].[Id] = [g1].[SquadId] -) AS [t] ON [g].[FullName] = [t].[OwnerFullName] -ORDER BY [g].[FullName], [g].[Nickname] DESC, [g].[SquadId], [t].[Id], [t].[Nickname], [t].[SquadId], [t].[Id0], [t].[Nickname0], [t].[SquadId0]"); + LEFT JOIN ( + SELECT [g1].[Nickname], [g1].[HasSoulPatch], [g1].[SquadId] + FROM [Gears] AS [g1] + ) AS [t] ON [s].[Id] = [t].[SquadId] +) AS [t0] ON [g].[FullName] = [t0].[OwnerFullName] +ORDER BY [g].[FullName], [g].[Nickname] DESC, [g].[SquadId], [t0].[Id], [t0].[Nickname], [t0].[SquadId], [t0].[Id0], [t0].[Nickname0], [t0].[SquadId0]"); } public override async Task Correlated_collections_with_funky_orderby_complex_scenario2(bool async) @@ -4265,21 +4280,24 @@ public override async Task Correlated_collections_with_funky_orderby_complex_sce await base.Correlated_collections_with_funky_orderby_complex_scenario2(async); AssertSql( - @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t0].[FullName], [t0].[Nickname], [t0].[SquadId], [t0].[Id], [t0].[Nickname0], [t0].[SquadId0], [t0].[Id0], [t0].[Nickname00], [t0].[HasSoulPatch], [t0].[SquadId00] + @"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t1].[FullName], [t1].[Nickname], [t1].[SquadId], [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Nickname00], [t1].[HasSoulPatch], [t1].[SquadId00] FROM [Gears] AS [g] LEFT JOIN ( - SELECT [g0].[FullName], [g0].[Nickname], [g0].[SquadId], [t].[Id], [t].[Nickname] AS [Nickname0], [t].[SquadId] AS [SquadId0], [t].[Id0], [t].[Nickname0] AS [Nickname00], [t].[HasSoulPatch], [t].[SquadId0] AS [SquadId00], [g0].[HasSoulPatch] AS [HasSoulPatch0], [t].[IsAutomatic], [t].[Name], [g0].[LeaderNickname], [g0].[LeaderSquadId] + SELECT [g0].[FullName], [g0].[Nickname], [g0].[SquadId], [t0].[Id], [t0].[Nickname] AS [Nickname0], [t0].[SquadId] AS [SquadId0], [t0].[Id0], [t0].[Nickname0] AS [Nickname00], [t0].[HasSoulPatch], [t0].[SquadId0] AS [SquadId00], [g0].[HasSoulPatch] AS [HasSoulPatch0], [t0].[IsAutomatic], [t0].[Name], [g0].[LeaderNickname], [g0].[LeaderSquadId] FROM [Gears] AS [g0] LEFT JOIN ( - SELECT [w].[Id], [g1].[Nickname], [g1].[SquadId], [s].[Id] AS [Id0], [g2].[Nickname] AS [Nickname0], [g2].[HasSoulPatch], [g2].[SquadId] AS [SquadId0], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName] + SELECT [w].[Id], [g1].[Nickname], [g1].[SquadId], [s].[Id] AS [Id0], [t].[Nickname] AS [Nickname0], [t].[HasSoulPatch], [t].[SquadId] AS [SquadId0], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN [Gears] AS [g1] ON [w].[OwnerFullName] = [g1].[FullName] LEFT JOIN [Squads] AS [s] ON [g1].[SquadId] = [s].[Id] - LEFT JOIN [Gears] AS [g2] ON [s].[Id] = [g2].[SquadId] - ) AS [t] ON [g0].[FullName] = [t].[OwnerFullName] -) AS [t0] ON ([g].[Nickname] = [t0].[LeaderNickname]) AND ([g].[SquadId] = [t0].[LeaderSquadId]) + LEFT JOIN ( + SELECT [g2].[Nickname], [g2].[HasSoulPatch], [g2].[SquadId] + FROM [Gears] AS [g2] + ) AS [t] ON [s].[Id] = [t].[SquadId] + ) AS [t0] ON [g0].[FullName] = [t0].[OwnerFullName] +) AS [t1] ON ([g].[Nickname] = [t1].[LeaderNickname]) AND ([g].[SquadId] = [t1].[LeaderSquadId]) WHERE [g].[Discriminator] = N'Officer' -ORDER BY [g].[HasSoulPatch], [g].[LeaderNickname], [g].[FullName], [g].[Nickname], [g].[SquadId], [t0].[FullName], [t0].[HasSoulPatch0] DESC, [t0].[Nickname], [t0].[SquadId], [t0].[IsAutomatic], [t0].[Name] DESC, [t0].[Id], [t0].[Nickname0], [t0].[SquadId0], [t0].[Id0], [t0].[Nickname00], [t0].[SquadId00]"); +ORDER BY [g].[HasSoulPatch], [g].[LeaderNickname], [g].[FullName], [g].[Nickname], [g].[SquadId], [t1].[FullName], [t1].[HasSoulPatch0] DESC, [t1].[Nickname], [t1].[SquadId], [t1].[IsAutomatic], [t1].[Name] DESC, [t1].[Id], [t1].[Nickname0], [t1].[SquadId0], [t1].[Id0], [t1].[Nickname00], [t1].[SquadId00]"); } public override async Task Correlated_collection_with_top_level_FirstOrDefault(bool async) @@ -4326,14 +4344,17 @@ public override async Task Correlated_collection_with_top_level_Last_with_order_ await base.Correlated_collection_with_top_level_Last_with_order_by_on_inner(async); AssertSql( - @"SELECT [t].[Nickname], [t].[SquadId], [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId] + @"SELECT [t].[Nickname], [t].[SquadId], [t0].[Id], [t0].[AmmunitionType], [t0].[IsAutomatic], [t0].[Name], [t0].[OwnerFullName], [t0].[SynergyWithId] FROM ( SELECT TOP(1) [g].[Nickname], [g].[SquadId], [g].[FullName] FROM [Gears] AS [g] ORDER BY [g].[FullName] DESC ) AS [t] -LEFT JOIN [Weapons] AS [w] ON [t].[FullName] = [w].[OwnerFullName] -ORDER BY [t].[FullName] DESC, [t].[Nickname], [t].[SquadId], [w].[Name], [w].[Id]"); +LEFT JOIN ( + SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId] + FROM [Weapons] AS [w] +) AS [t0] ON [t].[FullName] = [t0].[OwnerFullName] +ORDER BY [t].[FullName] DESC, [t].[Nickname], [t].[SquadId], [t0].[Name], [t0].[Id]"); } public override async Task Null_semantics_on_nullable_bool_from_inner_join_subquery_is_fully_applied(bool async) @@ -5177,11 +5198,14 @@ public override async Task Cast_ordered_subquery_to_base_type_using_typed_ToArra await base.Cast_ordered_subquery_to_base_type_using_typed_ToArray(async); AssertSql( - @"SELECT [c].[Name], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Nickname], [g].[Rank], [g].[SquadId] + @"SELECT [c].[Name], [t].[CityOfBirthName], [t].[FullName], [t].[HasSoulPatch], [t].[LeaderNickname], [t].[LeaderSquadId], [t].[Nickname], [t].[Rank], [t].[SquadId] FROM [Cities] AS [c] -LEFT JOIN [Gears] AS [g] ON [c].[Name] = [g].[AssignedCityName] +LEFT JOIN ( + SELECT [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Nickname], [g].[Rank], [g].[SquadId], [g].[AssignedCityName] + FROM [Gears] AS [g] +) AS [t] ON [c].[Name] = [t].[AssignedCityName] WHERE [c].[Name] = N'Ephyra' -ORDER BY [c].[Name], [g].[Nickname] DESC, [g].[SquadId]"); +ORDER BY [c].[Name], [t].[Nickname] DESC, [t].[SquadId]"); } public override async Task Correlated_collection_with_complex_order_by_funcletized_to_constant_bool(bool async) @@ -5860,16 +5884,19 @@ public override async Task Project_collection_navigation_nested_with_take_compos await base.Project_collection_navigation_nested_with_take_composite_key(async); AssertSql( - @"SELECT [t].[Id], [g].[Nickname], [g].[SquadId], [t0].[Nickname], [t0].[SquadId], [t0].[AssignedCityName], [t0].[CityOfBirthName], [t0].[Discriminator], [t0].[FullName], [t0].[HasSoulPatch], [t0].[LeaderNickname], [t0].[LeaderSquadId], [t0].[Rank] + @"SELECT [t].[Id], [g].[Nickname], [g].[SquadId], [t1].[Nickname], [t1].[SquadId], [t1].[AssignedCityName], [t1].[CityOfBirthName], [t1].[Discriminator], [t1].[FullName], [t1].[HasSoulPatch], [t1].[LeaderNickname], [t1].[LeaderSquadId], [t1].[Rank] FROM [Tags] AS [t] LEFT JOIN [Gears] AS [g] ON ([t].[GearNickName] = [g].[Nickname]) AND ([t].[GearSquadId] = [g].[SquadId]) -OUTER APPLY ( - SELECT TOP(50) [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank] - FROM [Gears] AS [g0] - WHERE ([g].[Nickname] IS NOT NULL AND [g].[SquadId] IS NOT NULL) AND (([g].[Nickname] = [g0].[LeaderNickname]) AND ([g].[SquadId] = [g0].[LeaderSquadId])) -) AS [t0] +LEFT JOIN ( + SELECT [t0].[Nickname], [t0].[SquadId], [t0].[AssignedCityName], [t0].[CityOfBirthName], [t0].[Discriminator], [t0].[FullName], [t0].[HasSoulPatch], [t0].[LeaderNickname], [t0].[LeaderSquadId], [t0].[Rank] + FROM ( + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank], ROW_NUMBER() OVER(PARTITION BY [g0].[LeaderNickname], [g0].[LeaderSquadId] ORDER BY [g0].[Nickname], [g0].[SquadId]) AS [row] + FROM [Gears] AS [g0] + ) AS [t0] + WHERE [t0].[row] <= 50 +) AS [t1] ON (([g].[Nickname] = [t1].[LeaderNickname]) OR ([g].[Nickname] IS NULL AND [t1].[LeaderNickname] IS NULL)) AND ([g].[SquadId] = [t1].[LeaderSquadId]) WHERE [g].[Discriminator] = N'Officer' -ORDER BY [t].[Id], [g].[Nickname], [g].[SquadId], [t0].[Nickname], [t0].[SquadId]"); +ORDER BY [t].[Id], [g].[Nickname], [g].[SquadId], [t1].[Nickname], [t1].[SquadId]"); } public override async Task Project_collection_navigation_nested_composite_key(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs index c58501990d3..e139c8e16e7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs @@ -1223,17 +1223,20 @@ public override async Task Filtered_include_with_multiple_ordering(bool async) await base.Filtered_include_with_multiple_ordering(async); AssertSql( - @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate] + @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate] FROM [Customers] AS [c] OUTER APPLY ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] - ORDER BY [o].[OrderID] - OFFSET 1 ROWS -) AS [t] + SELECT [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate] + FROM ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] + FROM [Orders] AS [o] + WHERE [c].[CustomerID] = [o].[CustomerID] + ORDER BY [o].[OrderID] + OFFSET 1 ROWS + ) AS [t] +) AS [t0] WHERE [c].[CustomerID] LIKE N'F%' -ORDER BY [c].[CustomerID], [t].[OrderDate] DESC, [t].[OrderID]"); +ORDER BY [c].[CustomerID], [t0].[OrderDate] DESC, [t0].[OrderID]"); } private void AssertSql(params string[] expected) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index a6aca817a19..4ae4a4fae12 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -4731,15 +4731,18 @@ public override async Task AsQueryable_in_query_server_evals(bool async) await base.AsQueryable_in_query_server_evals(async); AssertSql( - @"SELECT [c].[CustomerID], [t].[OrderDate], [t].[OrderID] + @"SELECT [c].[CustomerID], [t0].[OrderDate], [t0].[OrderID] FROM [Customers] AS [c] -OUTER APPLY ( - SELECT TOP(1) [o].[OrderDate], [o].[OrderID] - FROM [Orders] AS [o] - WHERE ([c].[CustomerID] = [o].[CustomerID]) AND (DATEPART(year, [o].[OrderDate]) = 1998) - ORDER BY [o].[OrderID] -) AS [t] -ORDER BY [c].[CustomerID], [t].[OrderID]"); +LEFT JOIN ( + SELECT [t].[OrderDate], [t].[OrderID], [t].[CustomerID] + FROM ( + SELECT [o].[OrderDate], [o].[OrderID], [o].[CustomerID], ROW_NUMBER() OVER(PARTITION BY [o].[CustomerID] ORDER BY [o].[OrderID]) AS [row] + FROM [Orders] AS [o] + WHERE DATEPART(year, [o].[OrderDate]) = 1998 + ) AS [t] + WHERE [t].[row] <= 1 +) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID] +ORDER BY [c].[CustomerID], [t0].[OrderID]"); } public override async Task Subquery_DefaultIfEmpty_Any(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs index d36d68b59af..e12982ec9e1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs @@ -325,15 +325,19 @@ public override void Select_nested_collection_multi_level() base.Select_nested_collection_multi_level(); AssertSql( - @"SELECT [c].[CustomerID], [t].[OrderDate], [t].[OrderID] + @"SELECT [c].[CustomerID], [t0].[OrderDate], [t0].[OrderID] FROM [Customers] AS [c] -OUTER APPLY ( - SELECT TOP(3) [o].[OrderDate], [o].[OrderID] - FROM [Orders] AS [o] - WHERE ([c].[CustomerID] = [o].[CustomerID]) AND ([o].[OrderID] < 10500) -) AS [t] +LEFT JOIN ( + SELECT [t].[OrderDate], [t].[OrderID], [t].[CustomerID] + FROM ( + SELECT [o].[OrderDate], [o].[OrderID], [o].[CustomerID], ROW_NUMBER() OVER(PARTITION BY [o].[CustomerID] ORDER BY [o].[OrderID]) AS [row] + FROM [Orders] AS [o] + WHERE [o].[OrderID] < 10500 + ) AS [t] + WHERE [t].[row] <= 3 +) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID] WHERE [c].[CustomerID] LIKE N'A%' -ORDER BY [c].[CustomerID], [t].[OrderID]"); +ORDER BY [c].[CustomerID], [t0].[OrderID]"); } public override void Select_nested_collection_multi_level2() @@ -1024,7 +1028,7 @@ public override async Task SelectMany_correlated_with_outer_1(bool async) @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[City] AS [o] FROM [Customers] AS [c] CROSS APPLY ( - SELECT [c].[City], [o].[OrderID], [o].[CustomerID] + SELECT [c].[City], [o].[OrderID] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] ) AS [t]"); @@ -1053,7 +1057,7 @@ public override async Task SelectMany_correlated_with_outer_3(bool async) @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[City] AS [o] FROM [Customers] AS [c] OUTER APPLY ( - SELECT [c].[City], [o].[OrderID], [o].[CustomerID] + SELECT [c].[City], [o].[OrderID] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] ) AS [t]"); @@ -1218,7 +1222,7 @@ public override async Task SelectMany_whose_selector_references_outer_source(boo @"SELECT [t].[OrderDate], [t].[City] AS [CustomerCity] FROM [Customers] AS [c] CROSS APPLY ( - SELECT [o].[OrderDate], [c].[City], [o].[OrderID], [o].[CustomerID] + SELECT [o].[OrderDate], [c].[City], [o].[OrderID] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] ) AS [t]"); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs index 5e17ab47f0c..2e7e50b8084 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsQuerySqliteTest.cs @@ -13,18 +13,6 @@ public ComplexNavigationsQuerySqliteTest(ComplexNavigationsQuerySqliteFixture fi { } - [ConditionalTheory(Skip = "Issue #17230")] - public override Task SelectMany_with_navigation_filter_paging_and_explicit_DefaultIfEmpty(bool async) - { - return base.SelectMany_with_navigation_filter_paging_and_explicit_DefaultIfEmpty(async); - } - - [ConditionalTheory(Skip = "Issue #17230")] - public override Task Project_collection_navigation_nested_with_take(bool async) - { - return base.Project_collection_navigation_nested_with_take(async); - } - [ConditionalTheory(Skip = "Issue #17230")] public override Task Include_inside_subquery(bool async) { @@ -33,26 +21,10 @@ public override Task Include_inside_subquery(bool async) // Sqlite does not support cross/outer apply public override Task SelectMany_with_outside_reference_to_joined_table_correctly_translated_to_apply(bool async) => null; - public override Task Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(bool async) => null; - public override void Filtered_include_Skip_without_OrderBy() { } - public override void Filtered_include_Take_without_OrderBy() { } - public override Task Filtered_include_after_different_filtered_include_same_level(bool async) => null; public override Task Filtered_include_after_different_filtered_include_different_level(bool async) => null; - public override Task Filtered_include_after_reference_navigation(bool async) => null; - public override Task Filtered_include_and_non_filtered_include_on_same_navigation1(bool async) => null; - public override Task Filtered_include_and_non_filtered_include_on_same_navigation2(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Take(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Skip(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Skip_Take(bool async) => null; - public override void Filtered_include_context_accessed_inside_filter() { } - public override void Filtered_include_context_accessed_inside_filter_correlated() { } - public override Task Filtered_include_on_ThenInclude(bool async) => null; public override void Filtered_include_outer_parameter_used_inside_filter() { } - public override void Filtered_include_variable_used_inside_filter() { } - public override void Filtered_include_is_considered_loaded() { } public override Task Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(bool async) => null; public override Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only(bool async) => null; - public override Task Filtered_include_same_filter_set_on_same_navigation_twice(bool async) => null; public override Task Filtered_include_same_filter_set_on_same_navigation_twice_followed_by_ThenIncludes(bool async) => null; public override Task Filtered_include_complex_three_level_with_middle_having_filter1(bool async) => null; public override Task Filtered_include_complex_three_level_with_middle_having_filter2(bool async) => null; diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsWeakQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsWeakQuerySqliteTest.cs index 1877628df6f..a94f75e1a47 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsWeakQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsWeakQuerySqliteTest.cs @@ -14,40 +14,12 @@ public ComplexNavigationsWeakQuerySqliteTest(ComplexNavigationsWeakQuerySqliteFi { } - [ConditionalTheory(Skip = "Issue #17230")] - public override Task SelectMany_with_navigation_filter_paging_and_explicit_DefaultIfEmpty(bool async) - { - return base.SelectMany_with_navigation_filter_paging_and_explicit_DefaultIfEmpty(async); - } - - [ConditionalTheory(Skip = "Issue #17230")] - public override Task Project_collection_navigation_nested_with_take(bool async) - { - return base.Project_collection_navigation_nested_with_take(async); - } - // Sqlite does not support cross/outer apply public override Task SelectMany_with_outside_reference_to_joined_table_correctly_translated_to_apply(bool async) => null; - public override Task Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(bool async) => null; - public override void Filtered_include_Skip_without_OrderBy() { } - public override void Filtered_include_Take_without_OrderBy() { } - public override Task Filtered_include_after_different_filtered_include_same_level(bool async) => null; public override Task Filtered_include_after_different_filtered_include_different_level(bool async) => null; - public override Task Filtered_include_after_reference_navigation(bool async) => null; - public override Task Filtered_include_and_non_filtered_include_on_same_navigation1(bool async) => null; - public override Task Filtered_include_and_non_filtered_include_on_same_navigation2(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Take(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Skip(bool async) => null; - public override Task Filtered_include_basic_OrderBy_Skip_Take(bool async) => null; - public override void Filtered_include_context_accessed_inside_filter() { } - public override void Filtered_include_context_accessed_inside_filter_correlated() { } - public override Task Filtered_include_on_ThenInclude(bool async) => null; - public override void Filtered_include_variable_used_inside_filter() { } - public override void Filtered_include_is_considered_loaded() { } public override Task Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(bool async) => null; public override Task Filtered_include_complex_three_level_with_middle_having_filter1(bool async) => null; public override Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only(bool async) => null; - public override Task Filtered_include_same_filter_set_on_same_navigation_twice(bool async) => null; public override Task Filtered_include_same_filter_set_on_same_navigation_twice_followed_by_ThenIncludes(bool async) => null; public override Task Filtered_include_complex_three_level_with_middle_having_filter2(bool async) => null; } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 10117e94377..5d4c6e82426 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -78,10 +78,6 @@ public override Task DateTimeOffset_Date_returns_datetime(bool async) public override Task Subquery_projecting_non_nullable_scalar_contains_non_nullable_value_doesnt_need_null_expansion_negated(bool async) => null; - [ConditionalTheory(Skip = "Issue #17230")] - public override Task Project_collection_navigation_nested_with_take_composite_key(bool async) - => base.Project_collection_navigation_nested_with_take_composite_key(async); - public override async Task Select_datetimeoffset_comparison_in_projection(bool async) { await base.Select_datetimeoffset_comparison_in_projection(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs index f87906e07cd..354177e998d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs @@ -239,8 +239,6 @@ public override Task Complex_nested_query_doesnt_try_binding_to_grandparent_when public override Task SelectMany_correlated_subquery_hard(bool async) => null; - public override Task AsQueryable_in_query_server_evals(bool async) => null; - public override async Task Concat_string_int(bool async) { await base.Concat_string_int(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs index 8feb9ac400d..4d55679a883 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs @@ -136,10 +136,6 @@ public override Task Project_single_element_from_collection_with_multiple_OrderB => base.Project_single_element_from_collection_with_multiple_OrderBys_Take_and_FirstOrDefault_2(async); // Sqlite does not support cross/outer apply - public override void Select_nested_collection_multi_level() - { - } - public override Task SelectMany_correlated_with_outer_1(bool async) => null; public override Task SelectMany_correlated_with_outer_2(bool async) => null;