diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index 515779e518a..ec06eac505e 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -1061,14 +1061,6 @@ public static string UnableToBindMemberToEntityProjection(object? memberType, ob GetString("UnableToBindMemberToEntityProjection", nameof(memberType), nameof(member), nameof(entityType)), memberType, member, entityType); - /// - /// The query has been configured to use '{splitQueryEnumValue}', but contains a collection in the 'Select' call which could not be split into a separate query. Remove '{splitQueryMethodName}' if applied, or add '{singleQueryMethodName}' to the query. - /// - public static string UnableToSplitCollectionProjectionInSplitQuery(object? splitQueryEnumValue, object? splitQueryMethodName, object? singleQueryMethodName) - => string.Format( - GetString("UnableToSplitCollectionProjectionInSplitQuery", nameof(splitQueryEnumValue), nameof(splitQueryMethodName), nameof(singleQueryMethodName)), - splitQueryEnumValue, splitQueryMethodName, singleQueryMethodName); - /// /// Unhandled expression '{expression}' of type '{expressionType}' encountered in '{visitor}'. /// diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 39dab27797d..30e53e273fd 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -748,9 +748,6 @@ Unable to bind '{memberType}.{member}' to an entity projection of '{entityType}'. - - The query has been configured to use '{splitQueryEnumValue}', but contains a collection in the 'Select' call which could not be split into a separate query. Remove '{splitQueryMethodName}' if applied, or add '{singleQueryMethodName}' to the query. - Unhandled expression '{expression}' of type '{expressionType}' encountered in '{visitor}'. diff --git a/src/EFCore.Relational/Query/Internal/SplitIncludeRewritingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/SplitIncludeRewritingExpressionVisitor.cs deleted file mode 100644 index 7440cf7845a..00000000000 --- a/src/EFCore.Relational/Query/Internal/SplitIncludeRewritingExpressionVisitor.cs +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace Microsoft.EntityFrameworkCore.Query.Internal -{ - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public class SplitIncludeRewritingExpressionVisitor : ExpressionVisitor - { - /// - protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression) - { - if (methodCallExpression.Method.DeclaringType == typeof(Queryable) - && methodCallExpression.Method.IsGenericMethod) - { - var genericMethod = methodCallExpression.Method.GetGenericMethodDefinition(); - Expression source = methodCallExpression; - var singleResult = false; - var reverseOrdering = false; - if (genericMethod == QueryableMethods.FirstOrDefaultWithoutPredicate - || genericMethod == QueryableMethods.FirstWithoutPredicate - || genericMethod == QueryableMethods.SingleOrDefaultWithoutPredicate - || genericMethod == QueryableMethods.SingleWithoutPredicate) - { - singleResult = true; - source = methodCallExpression.Arguments[0]; - } - - if (genericMethod == QueryableMethods.LastOrDefaultWithoutPredicate - || genericMethod == QueryableMethods.LastWithoutPredicate) - { - singleResult = true; - reverseOrdering = true; - source = methodCallExpression.Arguments[0]; - } - - if (source is MethodCallExpression selectMethodCall - && selectMethodCall.Method.DeclaringType == typeof(Queryable) - && selectMethodCall.Method.IsGenericMethod - && selectMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.Select) - { - var selector = RewriteCollectionInclude( - selectMethodCall.Arguments[0], selectMethodCall.Arguments[1].UnwrapLambdaFromQuote(), singleResult, - reverseOrdering); - - source = selectMethodCall.Update( - selectMethodCall.Object!, - new[] { selectMethodCall.Arguments[0], Expression.Quote(selector) }); - - if (singleResult) - { - source = methodCallExpression.Update(methodCallExpression.Object!, new[] { source }); - } - - return source; - } - } - - return base.VisitMethodCall(methodCallExpression); - } - - private LambdaExpression RewriteCollectionInclude( - Expression source, - LambdaExpression selector, - bool singleResult, - bool reverseOrdering) - { - var selectorParameter = selector.Parameters[0]; - var selectorBody = selector.Body; - var sourceElementType = source.Type.GetSequenceType(); - - if (reverseOrdering) - { - source = Expression.Call( - QueryableMethods.Reverse.MakeGenericMethod(sourceElementType), - source); - } - - if (singleResult) - { - source = Expression.Call( - QueryableMethods.Take.MakeGenericMethod(sourceElementType), - source, - Expression.Constant(1)); - } - - selectorBody = new CollectionSelectManyInjectingExpressionVisitor( - this, source, sourceElementType, selectorParameter).Visit(selectorBody); - - return Expression.Lambda(selectorBody, selectorParameter); - } - - private sealed class CollectionSelectManyInjectingExpressionVisitor : ExpressionVisitor - { - private readonly SplitIncludeRewritingExpressionVisitor _parentVisitor; - private readonly Expression _parentQuery; - private readonly Type _sourceElementType; - private readonly ParameterExpression _parameterExpression; - - public CollectionSelectManyInjectingExpressionVisitor( - SplitIncludeRewritingExpressionVisitor parentVisitor, - Expression parentQuery, - Type sourceElementType, - ParameterExpression parameterExpression) - { - _parentQuery = new CloningExpressionVisitor().Visit(parentQuery); - _parentVisitor = parentVisitor; - _sourceElementType = sourceElementType; - _parameterExpression = parameterExpression; - } - - protected override Expression VisitExtension(Expression extensionExpression) - { - if (extensionExpression is MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression - && materializeCollectionNavigationExpression.Navigation.IsCollection) - { - var subquery = materializeCollectionNavigationExpression.Subquery; - // Extract last select from subquery - if (subquery is MethodCallExpression subqueryMethodCallExpression - && subqueryMethodCallExpression.Method.IsGenericMethod - && subqueryMethodCallExpression.Method.GetGenericMethodDefinition() == QueryableMethods.Select) - { - subquery = RewriteSubqueryToSelectMany(subqueryMethodCallExpression.Arguments[0]); - subquery = subqueryMethodCallExpression.Update(null!, new[] { subquery, subqueryMethodCallExpression.Arguments[1] }); - subquery = _parentVisitor.Visit(subquery); - } - else - { - subquery = RewriteSubqueryToSelectMany(subquery); - } - - return materializeCollectionNavigationExpression.Update(subquery); - } - - return base.VisitExtension(extensionExpression); - } - - private Expression RewriteSubqueryToSelectMany(Expression subquery) - { - var collectionElementType = subquery.Type.GetSequenceType(); - if (subquery.Type.GetGenericTypeDefinition() == typeof(IOrderedQueryable<>)) - { - subquery = Expression.Call( - QueryableMethods.Skip.MakeGenericMethod(collectionElementType), - subquery, - Expression.Constant(0)); - } - - var newParameter = Expression.Parameter(_parameterExpression.Type); - subquery = ReplacingExpressionVisitor.Replace(_parameterExpression, newParameter, subquery); - - // Collection selector body is IQueryable, we need to adjust the type to IEnumerable, to match the SelectMany signature - // therefore the delegate type is specified explicitly - var collectionSelectorLambdaType = typeof(Func<,>).MakeGenericType( - _sourceElementType, - typeof(IEnumerable<>).MakeGenericType(collectionElementType)); - - return Expression.Call( - QueryableMethods.SelectManyWithoutCollectionSelector.MakeGenericMethod(_sourceElementType, collectionElementType), - _parentQuery, - Expression.Quote(Expression.Lambda(collectionSelectorLambdaType, subquery, newParameter))); - } - - private sealed class CloningExpressionVisitor : ExpressionVisitor - { - protected override Expression VisitLambda(Expression lambdaExpression) - { - var body = Visit(lambdaExpression.Body); - var newParameters = CopyParameters(lambdaExpression.Parameters); - body = new ReplacingExpressionVisitor(lambdaExpression.Parameters, newParameters).Visit(body); - - // TODO-Nullable bug - return lambdaExpression.Update(body, newParameters)!; - } - - private static IReadOnlyList CopyParameters(IReadOnlyList parameters) - { - var newParameters = new List(); - foreach (var parameter in parameters) - { - newParameters.Add(Expression.Parameter(parameter.Type, parameter.Name)); - } - - return newParameters; - } - } - } - } -} diff --git a/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessor.cs b/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessor.cs index ad264264850..748c6985f62 100644 --- a/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryTranslationPreprocessor.cs @@ -44,15 +44,5 @@ public override Expression NormalizeQueryableMethod(Expression expression) return expression; } - - /// - public override Expression Process(Expression query) - { - query = base.Process(query); - - return _relationalQueryCompilationContext.QuerySplittingBehavior == QuerySplittingBehavior.SplitQuery - ? new SplitIncludeRewritingExpressionVisitor().Visit(query) - : query; - } } } diff --git a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs index ce77c064e5f..7cc59f39c9d 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs @@ -17,7 +17,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions /// not used in application code. /// /// - public class FromSqlExpression : TableExpressionBase + public class FromSqlExpression : TableExpressionBase, ICloneable { /// /// Creates a new instance of the class. @@ -95,6 +95,9 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) return this; } + /// + public virtual object Clone() => new FromSqlExpression(Alias, Sql, Arguments); + /// protected override void Print(ExpressionPrinter expressionPrinter) { diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs index 05937c1185e..4feee62567e 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs @@ -712,11 +712,15 @@ public SelectExpressionVerifyingExpressionVisitor(IEnumerable new SelectExpressionVerifyingExpressionVisitor(tableReferencesInScope) .Visit(expression); } + + private sealed class CloningExpressionVisitor : ExpressionVisitor + { + [return: NotNullIfNotNull("expression")] + public override Expression? Visit(Expression? expression) + { + if (expression is SelectExpression selectExpression) + { + // We ignore projection binding related elements as we don't want to copy them over for top level + // Nested level will have _projection populated and no binding elements + var newProjections = selectExpression._projection.Select(Visit).ToList(); + + var newTables = selectExpression._tables.Select(Visit).ToList(); + // Since we are cloning we need to generate new table references + // In other cases (like VisitChildren), we just reuse the same table references and update the SelectExpression inside it. + // We initially assign old SelectExpression in table references and later update it once we construct clone + var newTableReferences = selectExpression._tableReferences + .Select(e => new TableReferenceExpression(selectExpression, e.Alias)).ToList(); + Check.DebugAssert( + newTables.Select(e => GetAliasFromTableExpressionBase(e)).SequenceEqual(newTableReferences.Select(e => e.Alias)), + "Alias of updated tables must match the old tables."); + + var predicate = (SqlExpression?)Visit(selectExpression.Predicate); + var newGroupBy = selectExpression._groupBy.Select(Visit) + .Where(e => !(e is SqlConstantExpression || e is SqlParameterExpression)) + .ToList(); + var havingExpression = (SqlExpression?)Visit(selectExpression.Having); + var newOrderings = selectExpression._orderings.Select(Visit).ToList(); + var offset = (SqlExpression?)Visit(selectExpression.Offset); + var limit = (SqlExpression?)Visit(selectExpression.Limit); + + var newSelectExpression = new SelectExpression(selectExpression.Alias, newProjections, newTables, newTableReferences, newGroupBy, newOrderings) + { + Predicate = predicate, + Having = havingExpression, + Offset = offset, + Limit = limit, + IsDistinct = selectExpression.IsDistinct, + Tags = selectExpression.Tags, + _usedAliases = selectExpression._usedAliases.ToHashSet() + }; + + newSelectExpression._tptLeftJoinTables.AddRange(selectExpression._tptLeftJoinTables); + // Since identifiers are ColumnExpression, they are not visited since they don't contain SelectExpression inside it. + newSelectExpression._identifier.AddRange(selectExpression._identifier); + newSelectExpression._childIdentifiers.AddRange(selectExpression._childIdentifiers); + + // Remap tableReferences in new select expression + foreach (var tableReference in newTableReferences) + { + tableReference.UpdateTableReference(selectExpression, newSelectExpression); + } + + // Now that we have SelectExpression, we visit all components and update table references inside columns + newSelectExpression = (SelectExpression)new ColumnExpressionReplacingExpressionVisitor(selectExpression, newSelectExpression) + .Visit(newSelectExpression); + + return newSelectExpression; + + } + + return expression is ICloneable cloneable ? (Expression)cloneable.Clone() : base.Visit(expression); + } + } + + private sealed class ColumnExpressionReplacingExpressionVisitor : ExpressionVisitor + { + private readonly SelectExpression _oldSelectExpression; + private readonly Dictionary _newTableReferences; + + public ColumnExpressionReplacingExpressionVisitor(SelectExpression oldSelectExpression, SelectExpression newSelectExpression) + { + _oldSelectExpression = oldSelectExpression; + _newTableReferences = newSelectExpression._tableReferences.ToDictionary(e => e.Alias); + } + + [return: NotNullIfNotNull("expression")] + public override Expression? Visit(Expression? expression) + { + return expression is ConcreteColumnExpression concreteColumnExpression + && _oldSelectExpression.ContainsTableReference(concreteColumnExpression) + ? new ConcreteColumnExpression( + concreteColumnExpression.Name, + _newTableReferences[concreteColumnExpression.TableAlias], + concreteColumnExpression.Type, + concreteColumnExpression.TypeMapping!, + concreteColumnExpression.IsNullable) + : base.Visit(expression); + } + } } } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index b47a8cffe36..f2412f2b1c7 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -393,6 +393,10 @@ public void ApplyDistinct() /// /// Adds expressions from projection mapping to projection if not done already. /// + /// Current shaper expression which will shape results of this select expression. + /// The result cardinality of this query expression. + /// The query splitting behavior to use when applying projection for nested collections. + /// Returns modified shaper expression to shape results of this select expression. public Expression ApplyProjection( Expression shaperExpression, ResultCardinality resultCardinality, QuerySplittingBehavior querySplittingBehavior) { @@ -404,6 +408,8 @@ public Expression ApplyProjection( if (_clientProjections.Count > 0) { EntityShaperNullableMarkingExpressionVisitor? entityShaperNullableMarkingExpressionVisitor = null; + CloningExpressionVisitor? cloningExpressionVisitor = null; + var pushdownOccurred = false; if (_clientProjections.Any(e => e is ShapedQueryExpression)) { if (Limit != null @@ -412,15 +418,43 @@ public Expression ApplyProjection( || GroupBy.Count > 0) { PushdownIntoSubqueryInternal(); + pushdownOccurred = true; } - entityShaperNullableMarkingExpressionVisitor = new EntityShaperNullableMarkingExpressionVisitor(); + entityShaperNullableMarkingExpressionVisitor = new(); + cloningExpressionVisitor = new(); } + SelectExpression? baseSelectExpression = null; + if (querySplittingBehavior == QuerySplittingBehavior.SplitQuery + && _clientProjections.Any(e => e is ShapedQueryExpression sqe && sqe.ResultCardinality == ResultCardinality.Enumerable)) + { + baseSelectExpression = (SelectExpression)cloningExpressionVisitor!.Visit(this); + if (pushdownOccurred + && (resultCardinality == ResultCardinality.Single + || resultCardinality == ResultCardinality.SingleOrDefault) + && baseSelectExpression.Tables[0] is SelectExpression nestedSelectExpression + && nestedSelectExpression.Limit is SqlConstantExpression limitConstantExpression + && limitConstantExpression.Value is int limitValue + && limitValue == 2) + { + nestedSelectExpression.Limit = new SqlConstantExpression(Constant(1), limitConstantExpression.TypeMapping); + } + } + + var earlierClientProjectionCount = _clientProjections.Count; var newClientProjections = new List(); var clientProjectionIndexMap = new List(); var remappingRequired = false; for (var i = 0; i < _clientProjections.Count; i++) { + if (i == earlierClientProjectionCount) + { + // Since we lift nested client projections for single results up, we may need to re-clone the baseSelectExpression + // again so it does contain the single result subquery too. We erase projections for it since it would be non-empty. + earlierClientProjectionCount = _clientProjections.Count; + baseSelectExpression = (SelectExpression)cloningExpressionVisitor!.Visit(this); + baseSelectExpression._projection.Clear(); + } var value = _clientProjections[i]; switch (value) { @@ -531,131 +565,76 @@ static Expression RemoveConvert(Expression expression) if (querySplittingBehavior == QuerySplittingBehavior.SplitQuery) { - var containsReferenceToOuter = new SelectExpressionCorrelationFindingExpressionVisitor(this) - .ContainsOuterReference(innerSelectExpression); - if (containsReferenceToOuter) - { - throw new InvalidOperationException( - RelationalStrings.UnableToSplitCollectionProjectionInSplitQuery( - $"{nameof(QuerySplittingBehavior)}.{QuerySplittingBehavior.SplitQuery}", - nameof(RelationalQueryableExtensions.AsSplitQuery), - nameof(RelationalQueryableExtensions.AsSingleQuery))); - } - - var identifierFromParent = _identifier; - if (innerSelectExpression.Tables.LastOrDefault(e => e is InnerJoinExpression) is InnerJoinExpression - collectionInnerJoinExpression) + var outerSelectExpression = (SelectExpression)cloningExpressionVisitor!.Visit(baseSelectExpression!); + innerSelectExpression = (SelectExpression)new ColumnExpressionReplacingExpressionVisitor(this, outerSelectExpression) + .Visit(innerSelectExpression); + + var actualParentIdentifier = _identifier.Take(outerSelectExpression._identifier.Count).ToList(); + var containsOrdering = innerSelectExpression.Orderings.Count > 0; + List? orderingsToBeErased = null; + if (containsOrdering + && innerSelectExpression.Limit == null + && innerSelectExpression.Offset == null) { - // This computes true parent identifier count for correlation. - // The last inner joined table in innerSelectExpression brings collection data. - // Further tables load additional data on the collection (hence uses outer pattern) - // So identifier not coming from there (which would be at the start only) are for correlation with parent. - // Parent can have additional identifier if a owned reference was expanded. - var actualParentIdentifierCount = innerSelectExpression._identifier - .TakeWhile(e => !ReferenceEquals(e.Column.Table, collectionInnerJoinExpression)) - .Count(); - identifierFromParent = _identifier.Take(actualParentIdentifierCount).ToList(); + orderingsToBeErased = innerSelectExpression.Orderings.ToList(); } - - var parentIdentifier = GetIdentifierAccessor(this, newClientProjections, identifierFromParent).Item1; - innerShaperExpression = innerSelectExpression.ApplyProjection( - innerShaperExpression, shapedQueryExpression.ResultCardinality, querySplittingBehavior); - - for (var j = 0; j < identifierFromParent.Count; j++) +#if DEBUG + Check.DebugAssert(!(new SelectExpressionCorrelationFindingExpressionVisitor(this) + .ContainsOuterReference(innerSelectExpression)), "Split query contains outer reference"); +#endif + var parentIdentifier = GetIdentifierAccessor(this, newClientProjections, actualParentIdentifier).Item1; + + outerSelectExpression.AddCrossApply(innerSelectExpression); + outerSelectExpression._clientProjections.AddRange(innerSelectExpression._clientProjections); + outerSelectExpression._aliasForClientProjections.AddRange(innerSelectExpression._aliasForClientProjections); + innerSelectExpression = outerSelectExpression; + + for (var j = 0; j < actualParentIdentifier.Count; j++) { - AppendOrdering(new OrderingExpression(identifierFromParent[j].Column, ascending: true)); + AppendOrdering(new OrderingExpression(actualParentIdentifier[j].Column, ascending: true)); + innerSelectExpression.AppendOrdering( + new OrderingExpression(innerSelectExpression._identifier[j].Column, ascending: true)); } - // Copy over ordering from previous collections - var innerOrderingExpressions = new List(); - for (var j = 0; j < innerSelectExpression.Tables.Count; j++) + // Copy over any nested ordering if there were any + if (containsOrdering) { - var table = innerSelectExpression.Tables[j]; - if (table is InnerJoinExpression collectionJoinExpression - && collectionJoinExpression.Table is SelectExpression collectionSelectExpression - && collectionSelectExpression.Predicate != null - && collectionSelectExpression.Tables.Count == 1 - && collectionSelectExpression.Tables[0] is SelectExpression rowNumberSubquery - && rowNumberSubquery.Projection.Select(pe => pe.Expression) - .OfType().SingleOrDefault() is RowNumberExpression rowNumberExpression) + var collectionJoinedInnerTable = ((JoinExpressionBase)innerSelectExpression._tables[^1]).Table; + var collectionJoinedTableReference = innerSelectExpression._tableReferences[^1]; + var innerOrderingExpressions = new List(); + if (orderingsToBeErased != null) { - var collectionSelectExpressionTableReference = innerSelectExpression._tableReferences[j]; - var rowNumberSubqueryTableReference = collectionSelectExpression._tableReferences.Single(); - foreach (var partition in rowNumberExpression.Partitions) - { - innerOrderingExpressions.Add( - new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn( - collectionSelectExpressionTableReference, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, partition)), - ascending: true)); - } - - foreach (var ordering in rowNumberExpression.Orderings) + var subquery = (SelectExpression)collectionJoinedInnerTable; + // Ordering was present but erased so we add again + foreach (var ordering in orderingsToBeErased) { innerOrderingExpressions.Add( new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn( - collectionSelectExpressionTableReference, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, ordering.Expression)), + subquery.GenerateOuterColumn(collectionJoinedTableReference, ordering.Expression), ordering.IsAscending)); } } - - if (table is CrossApplyExpression collectionApplyExpression - && collectionApplyExpression.Table is SelectExpression collectionSelectExpression2 - && collectionSelectExpression2.Orderings.Count > 0) + else { - var collectionSelectExpressionTableReference = innerSelectExpression._tableReferences[j]; - foreach (var ordering in collectionSelectExpression2.Orderings) - { - if (innerSelectExpression._identifier.Any(e => e.Column.Equals(ordering.Expression))) - { - continue; - } + GetOrderingsFromInnerTable( + collectionJoinedInnerTable, + collectionJoinedTableReference, + innerOrderingExpressions); + } - innerOrderingExpressions.Add( - new OrderingExpression( - collectionSelectExpression2.GenerateOuterColumn(collectionSelectExpressionTableReference, ordering.Expression), - ordering.IsAscending)); - } + foreach (var ordering in innerOrderingExpressions) + { + innerSelectExpression.AppendOrdering(ordering); } } + innerShaperExpression = innerSelectExpression.ApplyProjection( + innerShaperExpression, shapedQueryExpression.ResultCardinality, querySplittingBehavior); + var (childIdentifier, childIdentifierValueComparers) = GetIdentifierAccessor( innerSelectExpression, innerSelectExpression._clientProjections, - innerSelectExpression._identifier.Take(identifierFromParent.Count)); - - var identifierIndex = 0; - var orderingIndex = 0; - for (var j = 0; j < Orderings.Count; j++) - { - var outerOrdering = Orderings[j]; - if (identifierIndex < identifierFromParent.Count - && outerOrdering.Expression.Equals(identifierFromParent[identifierIndex].Column)) - { - innerSelectExpression.AppendOrdering( - new OrderingExpression( - innerSelectExpression._identifier[identifierIndex].Column, ascending: true)); - identifierIndex++; - } - else - { - if (j < innerSelectExpression.Orderings.Count) - { - continue; - } - - innerSelectExpression.AppendOrdering(innerOrderingExpressions[orderingIndex]); - orderingIndex++; - } - } - - foreach (var orderingExpression in innerOrderingExpressions.Skip(orderingIndex)) - { - innerSelectExpression.AppendOrdering(orderingExpression); - } + innerSelectExpression._identifier.Take(_identifier.Count)); var result = new SplitCollectionInfo( parentIdentifier, childIdentifier, childIdentifierValueComparers, @@ -679,54 +658,11 @@ static Expression RemoveConvert(Expression expression) innerShaperExpression, shapedQueryExpression.ResultCardinality, querySplittingBehavior); AddJoin(JoinType.OuterApply, ref innerSelectExpression); var innerOrderingExpressions = new List(); - var joinedTable = innerSelectExpression.Tables.Single(); - if (joinedTable is SelectExpression collectionSelectExpression - && collectionSelectExpression.Predicate != null - && collectionSelectExpression.Tables.Count == 1 - && collectionSelectExpression.Tables[0] is SelectExpression rowNumberSubquery - && rowNumberSubquery.Projection.Select(pe => pe.Expression) - .OfType().SingleOrDefault() is RowNumberExpression rowNumberExpression) - { - var collectionSelectExpressionTableReference = innerSelectExpression._tableReferences.Single(); - var rowNumberSubqueryTableReference = collectionSelectExpression._tableReferences.Single(); - foreach (var partition in rowNumberExpression.Partitions) - { - innerOrderingExpressions.Add( - new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn( - collectionSelectExpressionTableReference, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, partition)), - ascending: true)); - } - - foreach (var ordering in rowNumberExpression.Orderings) - { - innerOrderingExpressions.Add( - new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn( - collectionSelectExpressionTableReference, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, ordering.Expression)), - ordering.IsAscending)); - } - } - else if (joinedTable is SelectExpression collectionSelectExpression2 - && collectionSelectExpression2.Orderings.Count > 0) - { - var collectionSelectExpressionTableReference = innerSelectExpression._tableReferences.Single(); - foreach (var ordering in collectionSelectExpression2.Orderings) - { - if (innerSelectExpression._identifier.Any(e => e.Column.Equals(ordering.Expression))) - { - continue; - } - innerOrderingExpressions.Add( - new OrderingExpression( - collectionSelectExpression2.GenerateOuterColumn(collectionSelectExpressionTableReference, ordering.Expression), - ordering.IsAscending)); - } - } - else + if (!GetOrderingsFromInnerTable( + innerSelectExpression._tables[0], + innerSelectExpression._tableReferences[0], + innerOrderingExpressions)) { innerOrderingExpressions.AddRange(innerSelectExpression.Orderings); } @@ -809,6 +745,58 @@ static Expression RemoveConvert(Expression expression) return shaperExpression; + bool GetOrderingsFromInnerTable( + TableExpressionBase tableExpressionBase, + TableReferenceExpression tableReferenceExpression, + List orderings) + { + if (tableExpressionBase is SelectExpression joinedSubquery + && joinedSubquery.Predicate != null + && joinedSubquery.Tables.Count == 1 + && joinedSubquery.Tables[0] is SelectExpression rowNumberSubquery + && rowNumberSubquery.Projection.Select(pe => pe.Expression) + .OfType().SingleOrDefault() is RowNumberExpression rowNumberExpression) + { + var rowNumberSubqueryTableReference = joinedSubquery._tableReferences.Single(); + foreach (var partition in rowNumberExpression.Partitions) + { + orderings.Add( + new OrderingExpression( + joinedSubquery.GenerateOuterColumn( + tableReferenceExpression, + rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, partition)), + ascending: true)); + } + + foreach (var ordering in rowNumberExpression.Orderings) + { + orderings.Add( + new OrderingExpression( + joinedSubquery.GenerateOuterColumn( + tableReferenceExpression, + rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, ordering.Expression)), + ordering.IsAscending)); + } + + return true; + } + else if (tableExpressionBase is SelectExpression collectionSelectExpression + && collectionSelectExpression.Orderings.Count > 0) + { + foreach (var ordering in collectionSelectExpression.Orderings) + { + orderings.Add( + new OrderingExpression( + collectionSelectExpression.GenerateOuterColumn(tableReferenceExpression, ordering.Expression), + ordering.IsAscending)); + } + + return true; + } + + return false; + } + Expression CopyProjectionToOuter(SelectExpression innerSelectExpression, Expression innerShaperExpression) { var projectionIndexMap = new int[innerSelectExpression._projection.Count]; @@ -2838,6 +2826,8 @@ private SelectExpression Prune(IReadOnlyCollection? referencedColumns = } } + _identifier.Clear(); + _childIdentifiers.Clear(); var columnExpressionFindingExpressionVisitor = new ColumnExpressionFindingExpressionVisitor(); var columnsMap = columnExpressionFindingExpressionVisitor.FindColumns(this); var removedTableCount = 0; @@ -3071,17 +3061,17 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) Offset = (SqlExpression?)visitor.Visit(Offset); Limit = (SqlExpression?)visitor.Visit(Limit); - //var identifier = VisitList(_identifier.Select(e => e.Column).ToList(), inPlace: true, out _) - // .Zip(_identifier, (a,b) => (a, b.Comparer)) - // .ToList(); - //_identifier.Clear(); - //_identifier.AddRange(identifier); + var identifier = VisitList(_identifier.Select(e => e.Column).ToList(), inPlace: true, out _) + .Zip(_identifier, (a, b) => (a, b.Comparer)) + .ToList(); + _identifier.Clear(); + _identifier.AddRange(identifier); - //var childIdentifier = VisitList(_childIdentifiers.Select(e => e.Column).ToList(), inPlace: true, out _) - // .Zip(_childIdentifiers, (a, b) => (a, b.Comparer)) - // .ToList(); - //_childIdentifiers.Clear(); - //_childIdentifiers.AddRange(childIdentifier); + var childIdentifier = VisitList(_childIdentifiers.Select(e => e.Column).ToList(), inPlace: true, out _) + .Zip(_childIdentifiers, (a, b) => (a, b.Comparer)) + .ToList(); + _childIdentifiers.Clear(); + _childIdentifiers.AddRange(childIdentifier); return this; } @@ -3148,11 +3138,11 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) var limit = (SqlExpression?)visitor.Visit(Limit); changed |= limit != Limit; - //var identifier = VisitList(_identifier.Select(e => e.Column).ToList(), inPlace: false, out var identifierChanged); - //changed |= identifierChanged; + var identifier = VisitList(_identifier.Select(e => e.Column).ToList(), inPlace: false, out var identifierChanged); + changed |= identifierChanged; - //var childIdentifier = VisitList(_childIdentifiers.Select(e => e.Column).ToList(), inPlace: false, out var childIdentifierChanged); - //changed |= childIdentifierChanged; + var childIdentifier = VisitList(_childIdentifiers.Select(e => e.Column).ToList(), inPlace: false, out var childIdentifierChanged); + changed |= childIdentifierChanged; if (changed) { @@ -3170,8 +3160,10 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) _usedAliases = _usedAliases }; - //newSelectExpression._identifier.AddRange(identifier.Zip(_identifier).Select(e => (e.First, e.Second.Comparer))); - //newSelectExpression._childIdentifiers.AddRange(childIdentifier.Zip(_childIdentifiers).Select(e => (e.First, e.Second.Comparer))); + newSelectExpression._tptLeftJoinTables.AddRange(_tptLeftJoinTables); + + newSelectExpression._identifier.AddRange(identifier.Zip(_identifier).Select(e => (e.First, e.Second.Comparer))); + newSelectExpression._childIdentifiers.AddRange(childIdentifier.Zip(_childIdentifiers).Select(e => (e.First, e.Second.Comparer))); // Remap tableReferences in new select expression foreach (var tableReference in newTableReferences) diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs index 000fe556b79..4f99b33eb66 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs @@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions /// an issue at https://github.com/dotnet/efcore. /// /// - public sealed class TableExpression : TableExpressionBase + public sealed class TableExpression : TableExpressionBase, ICloneable { internal TableExpression(ITableBase table) : base(table.Name.Substring(0, 1).ToLowerInvariant()) @@ -66,6 +66,10 @@ public override string? Alias /// public ITableBase Table { get; } + /// + public object Clone() + => new TableExpression(Table) { Alias = Alias }; + /// public override bool Equals(object? obj) // This should be reference equal only. diff --git a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs index 74acf686400..833fb64c83b 100644 --- a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs +++ b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs @@ -85,6 +85,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter) expressionPrinter.AppendLine($"Navigation: {Navigation.DeclaringEntityType.DisplayName()}.{Navigation.Name},"); expressionPrinter.Append("subquery: "); expressionPrinter.Visit(Subquery); + expressionPrinter.Append(")"); } } } diff --git a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitQueryRelationalTestBase.cs index 53e11d95335..eaf3c2e9308 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitQueryRelationalTestBase.cs @@ -36,95 +36,5 @@ protected override Expression VisitExtension(Expression extensionExpression) return base.VisitExtension(extensionExpression); } } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Complex_query_with_let_collection_projection_FirstOrDefault(bool async) - { - return base.Complex_query_with_let_collection_projection_FirstOrDefault(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(bool async) - { - return base.Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Filtered_include_outer_parameter_used_inside_filter(bool async) - { - return base.Filtered_include_outer_parameter_used_inside_filter(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Include_inside_subquery(bool async) - { - return base.Include_inside_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Lift_projection_mapping_when_pushing_down_subquery(bool async) - { - return base.Lift_projection_mapping_when_pushing_down_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Null_check_in_anonymous_type_projection_should_not_be_removed(bool async) - { - return base.Null_check_in_anonymous_type_projection_should_not_be_removed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Null_check_in_Dto_projection_should_not_be_removed(bool async) - { - return base.Null_check_in_Dto_projection_should_not_be_removed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Project_collection_navigation_composed(bool async) - { - return base.Project_collection_navigation_composed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Project_collection_navigation_nested_with_take(bool async) - { - return base.Project_collection_navigation_nested_with_take(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_nav_prop_collection_one_to_many_required(bool async) - { - return base.Select_nav_prop_collection_one_to_many_required(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_subquery_single_nested_subquery(bool async) - { - return base.Select_subquery_single_nested_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_subquery_single_nested_subquery2(bool async) - { - return base.Select_subquery_single_nested_subquery2(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(bool async) - { - return base.SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Skip_Take_Select_collection_Skip_Take(bool async) - { - return base.Skip_Take_Select_collection_Skip_Take(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Take_Select_collection_Take(bool async) - { - return base.Take_Select_collection_Take(async); - } } } diff --git a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitSharedQueryTypeRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitSharedQueryTypeRelationalTestBase.cs index 272d93f7dad..7c329dc1b22 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitSharedQueryTypeRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsCollectionsSplitSharedQueryTypeRelationalTestBase.cs @@ -36,101 +36,5 @@ protected override Expression VisitExtension(Expression extensionExpression) return base.VisitExtension(extensionExpression); } } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Complex_query_with_let_collection_projection_FirstOrDefault(bool async) - { - return base.Complex_query_with_let_collection_projection_FirstOrDefault(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(bool async) - { - return base.Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Filtered_include_outer_parameter_used_inside_filter(bool async) - { - return base.Filtered_include_outer_parameter_used_inside_filter(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Include_inside_subquery(bool async) - { - return base.Include_inside_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Lift_projection_mapping_when_pushing_down_subquery(bool async) - { - return base.Lift_projection_mapping_when_pushing_down_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Null_check_in_anonymous_type_projection_should_not_be_removed(bool async) - { - return base.Null_check_in_anonymous_type_projection_should_not_be_removed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Null_check_in_Dto_projection_should_not_be_removed(bool async) - { - return base.Null_check_in_Dto_projection_should_not_be_removed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Project_collection_navigation_composed(bool async) - { - return base.Project_collection_navigation_composed(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Project_collection_navigation_nested_with_take(bool async) - { - return base.Project_collection_navigation_nested_with_take(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_nav_prop_collection_one_to_many_required(bool async) - { - return base.Select_nav_prop_collection_one_to_many_required(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_subquery_single_nested_subquery(bool async) - { - return base.Select_subquery_single_nested_subquery(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Select_subquery_single_nested_subquery2(bool async) - { - return base.Select_subquery_single_nested_subquery2(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(bool async) - { - return base.SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Skip_Take_Select_collection_Skip_Take(bool async) - { - return base.Skip_Take_Select_collection_Skip_Take(async); - } - - [ConditionalTheory(Skip = "Split query not fully supported yet.")] - public override Task Take_Select_collection_Take(bool async) - { - return base.Take_Select_collection_Take(async); - } - - [ConditionalTheory(Skip = "Split query bug")] - public override Task Include_reference_collection_order_by_reference_navigation(bool async) - { - return base.Include_reference_collection_order_by_reference_navigation(async); - } } } diff --git a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs index 31da9f7c326..0ea82ee152d 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs @@ -19,43 +19,6 @@ protected ComplexNavigationsQueryRelationalTestBase(TFixture fixture) { } - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Projecting_collection_with_FirstOrDefault_split_throws(bool async) - { - Assert.Equal( - RelationalStrings.UnableToSplitCollectionProjectionInSplitQuery( - "QuerySplittingBehavior.SplitQuery", "AsSplitQuery", "AsSingleQuery"), - (await Assert.ThrowsAsync( - () => AssertFirstOrDefault( - async, - ss => ss.Set() - .AsSplitQuery() - .Select(e => new { e.Id, Level2s = e.OneToMany_Optional1.ToList() }), - predicate: l => l.Id == 1, - asserter: (e, a) => - { - Assert.Equal(e.Id, a.Id); - AssertCollection(e.Level2s, a.Level2s); - }))).Message); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task Projecting_collection_with_FirstOrDefault_without_split_works(bool async) - { - return AssertFirstOrDefault( - async, - ss => ss.Set() - .Select(e => new { e.Id, Level2s = e.OneToMany_Optional1.ToList() }), - predicate: l => l.Id == 1, - asserter: (e, a) => - { - Assert.Equal(e.Id, a.Id); - AssertCollection(e.Level2s, a.Level2s); - }); - } - public override Task Complex_query_with_optional_navigations_and_client_side_evaluation(bool async) { return AssertTranslationFailed(() => base.Complex_query_with_optional_navigations_and_client_side_evaluation(async)); diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs index 3bc2d306412..4f80a861857 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs @@ -119,34 +119,11 @@ var orders Assert.Single(context.ChangeTracker.Entries()); } - public override Task Include_collection_with_last_no_orderby(bool async) + public override async Task Include_collection_with_last_no_orderby(bool async) { - return AssertTranslationFailedWithDetails( - () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSelectExpression); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_take(bool async) - { - return base.Multi_level_includes_are_applied_with_take(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_skip(bool async) - { - return base.Multi_level_includes_are_applied_with_skip(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_skip_take(bool async) - { - return base.Multi_level_includes_are_applied_with_skip_take(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested entity")] - public override Task Include_in_let_followed_by_FirstOrDefault(bool async) - { - return base.Include_in_let_followed_by_FirstOrDefault(async); + Assert.Equal( + RelationalStrings.LastUsedWithoutOrderBy(nameof(Queryable.Last)), + (await Assert.ThrowsAsync(() => base.Include_collection_with_last_no_orderby(async))).Message); } protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression) diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs index de18c77121a..3bfc9bf2200 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs @@ -107,34 +107,11 @@ var orders Assert.Equal(7, context.ChangeTracker.Entries().Count()); } - public override Task Include_collection_with_last_no_orderby(bool async) + public override async Task Include_collection_with_last_no_orderby(bool async) { - return AssertTranslationFailedWithDetails( - () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSelectExpression); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_take(bool async) - { - return base.Multi_level_includes_are_applied_with_take(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_skip(bool async) - { - return base.Multi_level_includes_are_applied_with_skip(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] - public override Task Multi_level_includes_are_applied_with_skip_take(bool async) - { - return base.Multi_level_includes_are_applied_with_skip_take(async); - } - - [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested entity")] - public override Task Include_in_let_followed_by_FirstOrDefault(bool async) - { - return base.Include_in_let_followed_by_FirstOrDefault(async); + Assert.Equal( + RelationalStrings.LastUsedWithoutOrderBy(nameof(Queryable.Last)), + (await Assert.ThrowsAsync(() => base.Include_collection_with_last_no_orderby(async))).Message); } protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression) diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs index 173a8a1c980..d6f54615def 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs @@ -1987,5 +1987,21 @@ public virtual async Task Filtered_include_calling_methods_directly_on_parameter .Include(l1 => l1.OneToMany_Optional1) .ThenInclude(l2 => l2.AsQueryable().Where(xx => xx.Id != 42))))).Message; } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Projecting_collection_with_FirstOrDefault(bool async) + { + return AssertFirstOrDefault( + async, + ss => ss.Set() + .Select(e => new { e.Id, Level2s = e.OneToMany_Optional1.ToList() }), + predicate: l => l.Id == 1, + asserter: (e, a) => + { + Assert.Equal(e.Id, a.Id); + AssertCollection(e.Level2s, a.Level2s); + }); + } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqlServerTest.cs index a28a0cb21e3..f75f358db6e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqlServerTest.cs @@ -1821,6 +1821,21 @@ OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY ORDER BY [t].[Id], [t0].[Id], [t0].[Id0]"); } + public override async Task Projecting_collection_with_FirstOrDefault(bool async) + { + await base.Projecting_collection_with_FirstOrDefault(async); + + AssertSql( + @"SELECT [t].[Id], [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 ( + SELECT TOP(1) [l].[Id] + FROM [LevelOne] AS [l] + WHERE [l].[Id] = 1 +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [t].[Id], [l0].[Id]"); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqlServerTest.cs index 32ba4ec3a7e..636b0ffeb01 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqlServerTest.cs @@ -47,17 +47,13 @@ public override async Task Filtered_include_OrderBy(bool async) FROM [LevelOne] AS [l] ORDER BY [l].[Id]", // - @"SELECT [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], [l].[Id] + @"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], [l].[Id] FROM [LevelOne] AS [l] INNER 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 0 < [t].[row] -) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name]"); + 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]"); } public override async Task Filtered_ThenInclude_OrderBy(bool async) @@ -74,18 +70,14 @@ FROM [LevelOne] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l].[Id], [l0].[Id]", // - @"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], [l].[Id], [l0].[Id] + @"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], [l].[Id], [l0].[Id] FROM [LevelOne] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] INNER 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] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Name]"); + 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] +ORDER BY [l].[Id], [l0].[Id], [t].[Name]"); } public override async Task Filtered_include_ThenInclude_OrderBy(bool async) @@ -97,37 +89,25 @@ public override async Task Filtered_include_ThenInclude_OrderBy(bool async) FROM [LevelOne] AS [l] ORDER BY [l].[Id]", // - @"SELECT [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], [l].[Id] + @"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], [l].[Id] FROM [LevelOne] AS [l] INNER 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 0 < [t].[row] -) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] -ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name]", + 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]", // - @"SELECT [t1].[Id], [t1].[Level2_Optional_Id], [t1].[Level2_Required_Id], [t1].[Name], [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], [l].[Id], [t0].[Id] + @"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], [l].[Id], [t].[Id] FROM [LevelOne] AS [l] INNER JOIN ( - SELECT [t].[Id], [t].[Name], [t].[OneToMany_Optional_Inverse2Id] - FROM ( - SELECT [l0].[Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Name]) AS [row] - FROM [LevelTwo] AS [l0] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] + SELECT [l0].[Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] INNER JOIN ( - SELECT [t2].[Id], [t2].[Level2_Optional_Id], [t2].[Level2_Required_Id], [t2].[Name], [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 ( - 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] DESC) AS [row] - FROM [LevelThree] AS [l1] - ) AS [t2] - WHERE 0 < [t2].[row] -) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Optional_Inverse3Id] -ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t1].[OneToMany_Optional_Inverse3Id], [t1].[Name] DESC"); + 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 [t0] ON [t].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [t].[Name], [t].[Id], [t0].[Name] DESC"); } public override async Task Filtered_include_basic_OrderBy_Take(bool async) @@ -348,7 +328,7 @@ 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], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name]", +ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id]", // @"SELECT [t1].[Id], [t1].[Level2_Optional_Id], [t1].[Level2_Required_Id], [t1].[Name], [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], [l].[Id], [t0].[Id] FROM [LevelOne] AS [l] @@ -370,7 +350,7 @@ FROM [LevelThree] AS [l1] ) AS [t2] WHERE 1 < [t2].[row] ) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Required_Inverse3Id] -ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t1].[OneToMany_Required_Inverse3Id], [t1].[Name] DESC"); +ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id], [t1].[OneToMany_Required_Inverse3Id], [t1].[Name] DESC"); } public override async Task Filtered_include_same_filter_set_on_same_navigation_twice(bool async) @@ -589,7 +569,7 @@ FROM [LevelThree] AS [l1] ) AS [t] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]", +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]", // @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id] FROM [LevelOne] AS [l] @@ -604,7 +584,7 @@ FROM [LevelThree] AS [l1] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Optional_Inverse4Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]", +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]", // @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id] FROM [LevelOne] AS [l] @@ -619,7 +599,7 @@ FROM [LevelThree] AS [l1] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Required_Inverse4Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]"); +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]"); } public override async Task Filtered_include_complex_three_level_with_middle_having_filter2(bool async) @@ -648,7 +628,7 @@ FROM [LevelThree] AS [l1] ) AS [t] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]", +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]", // @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id] FROM [LevelOne] AS [l] @@ -663,7 +643,7 @@ FROM [LevelThree] AS [l1] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Optional_Inverse4Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]", +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]", // @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id] FROM [LevelOne] AS [l] @@ -678,7 +658,7 @@ FROM [LevelThree] AS [l1] WHERE [t].[row] <= 1 ) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Required_Inverse4Id] -ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]"); +ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]"); } [ConditionalFact(Skip = "issue #24708")] @@ -767,7 +747,1812 @@ public override async Task Filtered_include_outer_parameter_used_inside_filter(b { await base.Filtered_include_outer_parameter_used_inside_filter(async); - AssertSql(" "); + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +CROSS APPLY [LevelTwo] AS [l0] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +CROSS APPLY [LevelTwo] AS [l0] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +CROSS APPLY [LevelTwo] AS [l0] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +CROSS APPLY [LevelTwo] AS [l0] +INNER JOIN [LevelThree] AS [l1] ON ([l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) AND ([l].[Id] <> [l1].[Id]) +ORDER BY [l].[Id], [l0].[Id]"); + } + + + public override async Task Select_nav_prop_collection_one_to_many_required(bool async) + { + await base.Select_nav_prop_collection_one_to_many_required(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"SELECT [l0].[Id], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Required_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(bool async) + { + await base.Complex_SelectMany_with_nested_navigations_and_explicit_DefaultIfEmpty_with_other_query_operators_composed_on_top(async); + + AssertSql( + @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [l1].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l12].[Id], [l13].[Id], [l14].[Id], [l14].[Name] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Required_Inverse4Id] +INNER JOIN ( + SELECT [l3].[Id], [l4].[Id] AS [Id0], [l5].[Id] AS [Id1], [l6].[Id] AS [Id2] + FROM [LevelFour] AS [l3] + INNER JOIN [LevelThree] AS [l4] ON [l3].[Level3_Required_Id] = [l4].[Id] + LEFT JOIN [LevelTwo] AS [l5] ON [l4].[Level2_Optional_Id] = [l5].[Id] + LEFT JOIN [LevelTwo] AS [l6] ON [l5].[Id] = [l6].[OneToMany_Required_Self_Inverse2Id] +) AS [t] ON [l2].[Id] = [t].[Id2] +LEFT JOIN ( + SELECT [l7].[Id], [l8].[Id] AS [Id0], [l9].[Id] AS [Id1], [l10].[Id] AS [Id2], [l10].[Level2_Optional_Id] AS [Level2_Optional_Id0] + FROM [LevelFour] AS [l7] + INNER JOIN [LevelThree] AS [l8] ON [l7].[Level3_Required_Id] = [l8].[Id] + INNER JOIN [LevelTwo] AS [l9] ON [l8].[Level2_Required_Id] = [l9].[Id] + LEFT JOIN [LevelThree] AS [l10] ON [l9].[Id] = [l10].[OneToMany_Required_Inverse3Id] +) AS [t0] ON [t].[Id2] = [t0].[Id2] +LEFT JOIN [LevelThree] AS [l11] ON [l2].[OneToMany_Optional_Inverse4Id] = [l11].[Id] +LEFT JOIN [LevelThree] AS [l12] ON [t].[Id2] = [l12].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l13] ON [t0].[Level2_Optional_Id0] = [l13].[Id] +LEFT JOIN [LevelThree] AS [l14] ON [l13].[Id] = [l14].[Level2_Required_Id] +WHERE ([l11].[Name] <> N'Foo') OR [l11].[Name] IS NULL +ORDER BY [l12].[Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l13].[Id], [l14].[Id]", + // + @"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], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l12].[Id], [l13].[Id], [l14].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Required_Inverse4Id] +INNER JOIN ( + SELECT [l3].[Id], [l4].[Id] AS [Id0], [l5].[Id] AS [Id1], [l6].[Id] AS [Id2] + FROM [LevelFour] AS [l3] + INNER JOIN [LevelThree] AS [l4] ON [l3].[Level3_Required_Id] = [l4].[Id] + LEFT JOIN [LevelTwo] AS [l5] ON [l4].[Level2_Optional_Id] = [l5].[Id] + LEFT JOIN [LevelTwo] AS [l6] ON [l5].[Id] = [l6].[OneToMany_Required_Self_Inverse2Id] +) AS [t] ON [l2].[Id] = [t].[Id2] +LEFT JOIN ( + SELECT [l7].[Id], [l8].[Id] AS [Id0], [l9].[Id] AS [Id1], [l10].[Id] AS [Id2], [l10].[Level2_Optional_Id] AS [Level2_Optional_Id0] + FROM [LevelFour] AS [l7] + INNER JOIN [LevelThree] AS [l8] ON [l7].[Level3_Required_Id] = [l8].[Id] + INNER JOIN [LevelTwo] AS [l9] ON [l8].[Level2_Required_Id] = [l9].[Id] + LEFT JOIN [LevelThree] AS [l10] ON [l9].[Id] = [l10].[OneToMany_Required_Inverse3Id] +) AS [t0] ON [t].[Id2] = [t0].[Id2] +LEFT JOIN [LevelThree] AS [l11] ON [l2].[OneToMany_Optional_Inverse4Id] = [l11].[Id] +LEFT JOIN [LevelThree] AS [l12] ON [t].[Id2] = [l12].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l13] ON [t0].[Level2_Optional_Id0] = [l13].[Id] +LEFT JOIN [LevelThree] AS [l14] ON [l13].[Id] = [l14].[Level2_Required_Id] +INNER JOIN ( + SELECT [l15].[Id], [l15].[Date], [l15].[Level1_Optional_Id], [l15].[Level1_Required_Id], [l15].[Name], [l15].[OneToMany_Optional_Inverse2Id], [l15].[OneToMany_Optional_Self_Inverse2Id], [l15].[OneToMany_Required_Inverse2Id], [l15].[OneToMany_Required_Self_Inverse2Id], [l15].[OneToOne_Optional_PK_Inverse2Id], [l15].[OneToOne_Optional_Self2Id] + FROM [LevelTwo] AS [l15] + WHERE [l15].[Id] <> 42 +) AS [t1] ON [t].[Id2] = [t1].[OneToMany_Optional_Self_Inverse2Id] +WHERE ([l11].[Name] <> N'Foo') OR [l11].[Name] IS NULL +ORDER BY [l12].[Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l13].[Id], [l14].[Id]"); + } + + public override async Task Project_collection_navigation(bool async) + { + await base.Project_collection_navigation(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Project_collection_navigation_nested(bool async) + { + await base.Project_collection_navigation_nested(async); + + AssertSql( + @"SELECT [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Project_collection_navigation_nested_with_take(bool async) + { + await base.Project_collection_navigation_nested_with_take(async); + + AssertSql( + @"SELECT [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER 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].[Id]) AS [row] + FROM [LevelThree] AS [l1] + ) AS [t] + WHERE [t].[row] <= 50 +) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Project_collection_navigation_using_ef_property(bool async) + { + await base.Project_collection_navigation_using_ef_property(async); + + AssertSql( + @"SELECT [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Project_collection_navigation_nested_anonymous(bool async) + { + await base.Project_collection_navigation_nested_anonymous(async); + + AssertSql( + @"SELECT [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Project_collection_navigation_composed(bool async) + { + await base.Project_collection_navigation_composed(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +WHERE [l].[Id] < 3 +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER 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] + WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +WHERE [l].[Id] < 3 +ORDER BY [l].[Id]"); + } + + public override async Task Project_collection_and_root_entity(bool async) + { + await base.Project_collection_and_root_entity(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Project_collection_and_include(bool async) + { + await base.Project_collection_and_include(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Project_navigation_and_collection(bool async) + { + await base.Project_navigation_and_collection(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Include_inside_subquery(bool async) + { + await base.Include_inside_subquery(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +WHERE [l].[Id] < 3 +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +CROSS 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 [l0].[Id] > 0 +) AS [t] +WHERE [l].[Id] < 3 +ORDER BY [l].[Id], [t].[Id]", + // + @"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], [l].[Id], [t].[Id] +FROM [LevelOne] AS [l] +CROSS APPLY ( + SELECT [l0].[Id] + FROM [LevelTwo] AS [l0] + WHERE [l0].[Id] > 0 +) AS [t] +INNER JOIN [LevelThree] AS [l1] ON [t].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +WHERE [l].[Id] < 3 +ORDER BY [l].[Id], [t].[Id]"); + } + + public override async Task Null_check_in_anonymous_type_projection_should_not_be_removed(bool async) + { + await base.Null_check_in_anonymous_type_projection_should_not_be_removed(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"SELECT [t].[c], [t].[Name], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT CASE + WHEN [l1].[Id] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END AS [c], [l1].[Name], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Null_check_in_Dto_projection_should_not_be_removed(bool async) + { + await base.Null_check_in_Dto_projection_should_not_be_removed(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"SELECT [t].[c], [t].[Name], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT CASE + WHEN [l1].[Id] IS NULL THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) + END AS [c], [l1].[Name], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task SelectMany_navigation_property_followed_by_select_collection_navigation(bool async) + { + await base.SelectMany_navigation_property_followed_by_select_collection_navigation(async); + + AssertSql( + @"SELECT [l0].[Id], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Multiple_SelectMany_navigation_property_followed_by_select_collection_navigation(bool async) + { + await base.Multiple_SelectMany_navigation_property_followed_by_select_collection_navigation(async); + + AssertSql( + @"SELECT [l1].[Id], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]", + // + @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [l1].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +INNER JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Optional_Inverse4Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]"); + } + + public override async Task SelectMany_navigation_property_with_include_and_followed_by_select_collection_navigation(bool async) + { + await base.SelectMany_navigation_property_with_include_and_followed_by_select_collection_navigation(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Required_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Lift_projection_mapping_when_pushing_down_subquery(bool async) + { + await base.Lift_projection_mapping_when_pushing_down_subquery(async); + + AssertSql( + @"@__p_0='25' + +SELECT [t].[Id], [t0].[Id], [t0].[c] +FROM ( + SELECT TOP(@__p_0) [l].[Id] + FROM [LevelOne] AS [l] +) AS [t] +LEFT JOIN ( + SELECT [t1].[Id], [t1].[c], [t1].[OneToMany_Required_Inverse2Id] + FROM ( + SELECT [l0].[Id], 1 AS [c], [l0].[OneToMany_Required_Inverse2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Required_Inverse2Id] ORDER BY [l0].[Id]) AS [row] + FROM [LevelTwo] AS [l0] + ) AS [t1] + WHERE [t1].[row] <= 1 +) AS [t0] ON [t].[Id] = [t0].[OneToMany_Required_Inverse2Id] +ORDER BY [t].[Id]", + // + @"@__p_0='25' + +SELECT [l0].[Id], [t].[Id] +FROM ( + SELECT TOP(@__p_0) [l].[Id] + FROM [LevelOne] AS [l] +) AS [t] +INNER JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[OneToMany_Required_Inverse2Id] +ORDER BY [t].[Id]"); + } + + public override async Task Select_subquery_single_nested_subquery(bool async) + { + await base.Select_subquery_single_nested_subquery(async); + + AssertSql( + @"SELECT [l].[Id], [t0].[Id], [t0].[c] +FROM [LevelOne] AS [l] +LEFT JOIN ( + SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse2Id] + FROM ( + SELECT 1 AS [c], [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], 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]", + // + @"SELECT [t1].[Id], [l].[Id], [t0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN ( + SELECT [t].[Id], [t].[OneToMany_Optional_Inverse2Id] + FROM ( + SELECT [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], 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] +INNER 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) + { + await base.Select_subquery_single_nested_subquery2(async); + + AssertSql( + @"SELECT [l].[Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"SELECT [l].[Id], [t].[Id], [t0].[Id], [t0].[c] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +LEFT JOIN ( + SELECT [t1].[c], [t1].[Id], [t1].[OneToMany_Optional_Inverse3Id] + FROM ( + SELECT 1 AS [c], [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Optional_Inverse3Id] ORDER BY [l1].[Id]) AS [row] + FROM [LevelThree] AS [l1] + ) AS [t1] + WHERE [t1].[row] <= 1 +) AS [t0] ON [t].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [t].[Id], [t0].[Id]", + // + @"SELECT [t2].[Id], [l].[Id], [t].[Id], [t0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +LEFT JOIN ( + SELECT [t1].[Id], [t1].[OneToMany_Optional_Inverse3Id] + FROM ( + SELECT [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Optional_Inverse3Id] ORDER BY [l1].[Id]) AS [row] + FROM [LevelThree] AS [l1] + ) AS [t1] + WHERE [t1].[row] <= 1 +) AS [t0] ON [t].[Id] = [t0].[OneToMany_Optional_Inverse3Id] +INNER JOIN ( + SELECT [l2].[Id], [l2].[OneToMany_Optional_Inverse4Id] + FROM [LevelFour] AS [l2] +) AS [t2] ON [t0].[Id] = [t2].[OneToMany_Optional_Inverse4Id] +ORDER BY [l].[Id], [t].[Id], [t0].[Id], [t2].[Id]"); + } + + public override async Task Queryable_in_subquery_works_when_final_projection_is_List(bool async) + { + await base.Queryable_in_subquery_works_when_final_projection_is_List(async); + + AssertSql(" "); + } + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(bool async) + { + await base.Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(async); + + AssertSql(" "); + } + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault(bool async) + { + await base.Complex_query_with_let_collection_projection_FirstOrDefault(async); + + AssertSql( + @"SELECT [l].[Id], [t0].[Id], [t0].[c] +FROM [LevelOne] AS [l] +LEFT JOIN ( + SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse2Id] + FROM ( + SELECT 1 AS [c], [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], 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] <= 1 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t0].[Id]", + // + @"SELECT [t1].[Name], [l].[Id], [t0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN ( + SELECT [t].[Id], [t].[OneToMany_Optional_Inverse2Id] + FROM ( + SELECT [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], 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] <= 1 +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +CROSS APPLY ( + SELECT [l1].[Name] + FROM [LevelOne] AS [l1] + WHERE EXISTS ( + SELECT 1 + FROM [LevelTwo] AS [l2] + WHERE ([l1].[Id] = [l2].[OneToMany_Optional_Inverse2Id]) AND ([l2].[Id] = [t0].[Id])) +) AS [t1] +ORDER BY [l].[Id], [t0].[Id]"); + } + + public override async Task SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(bool async) + { + await base.SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(async); + + AssertSql( + @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [l1].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l12].[Id], [l13].[Id], [l14].[Id], [l14].[Name] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Required_Inverse4Id] +INNER JOIN ( + SELECT [l3].[Id], [l4].[Id] AS [Id0], [l5].[Id] AS [Id1], [l6].[Id] AS [Id2] + FROM [LevelFour] AS [l3] + INNER JOIN [LevelThree] AS [l4] ON [l3].[Level3_Required_Id] = [l4].[Id] + LEFT JOIN [LevelTwo] AS [l5] ON [l4].[Level2_Optional_Id] = [l5].[Id] + LEFT JOIN [LevelTwo] AS [l6] ON [l5].[Id] = [l6].[OneToMany_Required_Self_Inverse2Id] +) AS [t] ON [l2].[Id] = [t].[Id2] +LEFT JOIN ( + SELECT [l7].[Id], [l8].[Id] AS [Id0], [l9].[Id] AS [Id1], [l10].[Id] AS [Id2], [l10].[Level2_Optional_Id] AS [Level2_Optional_Id0] + FROM [LevelFour] AS [l7] + INNER JOIN [LevelThree] AS [l8] ON [l7].[Level3_Required_Id] = [l8].[Id] + INNER JOIN [LevelTwo] AS [l9] ON [l8].[Level2_Required_Id] = [l9].[Id] + LEFT JOIN [LevelThree] AS [l10] ON [l9].[Id] = [l10].[OneToMany_Required_Inverse3Id] +) AS [t0] ON [t].[Id2] = [t0].[Id2] +LEFT JOIN [LevelThree] AS [l11] ON [l2].[OneToMany_Optional_Inverse4Id] = [l11].[Id] +LEFT JOIN [LevelThree] AS [l12] ON [t].[Id2] = [l12].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l13] ON [t0].[Level2_Optional_Id0] = [l13].[Id] +LEFT JOIN [LevelThree] AS [l14] ON [l13].[Id] = [l14].[Level2_Required_Id] +WHERE ([l11].[Name] <> N'Foo') OR [l11].[Name] IS NULL +ORDER BY [l12].[Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l13].[Id], [l14].[Id]", + // + @"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], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l12].[Id], [l13].[Id], [l14].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Required_Inverse4Id] +INNER JOIN ( + SELECT [l3].[Id], [l4].[Id] AS [Id0], [l5].[Id] AS [Id1], [l6].[Id] AS [Id2] + FROM [LevelFour] AS [l3] + INNER JOIN [LevelThree] AS [l4] ON [l3].[Level3_Required_Id] = [l4].[Id] + LEFT JOIN [LevelTwo] AS [l5] ON [l4].[Level2_Optional_Id] = [l5].[Id] + LEFT JOIN [LevelTwo] AS [l6] ON [l5].[Id] = [l6].[OneToMany_Required_Self_Inverse2Id] +) AS [t] ON [l2].[Id] = [t].[Id2] +LEFT JOIN ( + SELECT [l7].[Id], [l8].[Id] AS [Id0], [l9].[Id] AS [Id1], [l10].[Id] AS [Id2], [l10].[Level2_Optional_Id] AS [Level2_Optional_Id0] + FROM [LevelFour] AS [l7] + INNER JOIN [LevelThree] AS [l8] ON [l7].[Level3_Required_Id] = [l8].[Id] + INNER JOIN [LevelTwo] AS [l9] ON [l8].[Level2_Required_Id] = [l9].[Id] + LEFT JOIN [LevelThree] AS [l10] ON [l9].[Id] = [l10].[OneToMany_Required_Inverse3Id] +) AS [t0] ON [t].[Id2] = [t0].[Id2] +LEFT JOIN [LevelThree] AS [l11] ON [l2].[OneToMany_Optional_Inverse4Id] = [l11].[Id] +LEFT JOIN [LevelThree] AS [l12] ON [t].[Id2] = [l12].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l13] ON [t0].[Level2_Optional_Id0] = [l13].[Id] +LEFT JOIN [LevelThree] AS [l14] ON [l13].[Id] = [l14].[Level2_Required_Id] +INNER JOIN ( + SELECT [l15].[Id], [l15].[Date], [l15].[Level1_Optional_Id], [l15].[Level1_Required_Id], [l15].[Name], [l15].[OneToMany_Optional_Inverse2Id], [l15].[OneToMany_Optional_Self_Inverse2Id], [l15].[OneToMany_Required_Inverse2Id], [l15].[OneToMany_Required_Self_Inverse2Id], [l15].[OneToOne_Optional_PK_Inverse2Id], [l15].[OneToOne_Optional_Self2Id] + FROM [LevelTwo] AS [l15] + WHERE [l15].[Id] <> 42 +) AS [t1] ON [t].[Id2] = [t1].[OneToMany_Optional_Self_Inverse2Id] +WHERE ([l11].[Name] <> N'Foo') OR [l11].[Name] IS NULL +ORDER BY [l12].[Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t0].[Id], [t0].[Id0], [t0].[Id1], [t0].[Id2], [l11].[Id], [l13].[Id], [l14].[Id]"); + } + + public override async Task Take_Select_collection_Take(bool async) + { + await base.Take_Select_collection_Take(async); + + AssertSql( + @"@__p_0='1' + +SELECT [t].[Id], [t].[Name] +FROM ( + SELECT TOP(@__p_0) [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Id] +) AS [t] +ORDER BY [t].[Id]", + // + @"@__p_0='1' + +SELECT [t0].[Id], [t0].[Name], [t0].[Level1Id], [t0].[Level2Id], [t0].[Id0], [t0].[Date], [t0].[Name0], [t0].[OneToMany_Optional_Self_Inverse1Id], [t0].[OneToMany_Required_Self_Inverse1Id], [t0].[OneToOne_Optional_Self1Id], [t].[Id] +FROM ( + SELECT TOP(@__p_0) [l].[Id] + FROM [LevelOne] AS [l] + ORDER BY [l].[Id] +) AS [t] +CROSS APPLY ( + SELECT [t1].[Id], [t1].[Name], [t1].[OneToMany_Required_Inverse2Id] AS [Level1Id], [t1].[Level1_Required_Id] AS [Level2Id], [l0].[Id] AS [Id0], [l0].[Date], [l0].[Name] AS [Name0], [l0].[OneToMany_Optional_Self_Inverse1Id], [l0].[OneToMany_Required_Self_Inverse1Id], [l0].[OneToOne_Optional_Self1Id] + FROM ( + SELECT TOP(3) [l1].[Id], [l1].[Level1_Required_Id], [l1].[Name], [l1].[OneToMany_Required_Inverse2Id] + FROM [LevelTwo] AS [l1] + WHERE [t].[Id] = [l1].[OneToMany_Required_Inverse2Id] + ORDER BY [l1].[Id] + ) AS [t1] + INNER JOIN [LevelOne] AS [l0] ON [t1].[Level1_Required_Id] = [l0].[Id] +) AS [t0] +ORDER BY [t].[Id], [t0].[Id]"); + } + + public override async Task Skip_Take_Select_collection_Skip_Take(bool async) + { + await base.Skip_Take_Select_collection_Skip_Take(async); + + AssertSql( + @"@__p_0='1' + +SELECT [t].[Id], [t].[Name] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Id] + OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY +) AS [t] +ORDER BY [t].[Id]", + // + @"@__p_0='1' + +SELECT [t0].[Id], [t0].[Name], [t0].[Level1Id], [t0].[Level2Id], [t0].[Id0], [t0].[Date], [t0].[Name0], [t0].[OneToMany_Optional_Self_Inverse1Id], [t0].[OneToMany_Required_Self_Inverse1Id], [t0].[OneToOne_Optional_Self1Id], [t].[Id] +FROM ( + SELECT [l].[Id] + FROM [LevelOne] AS [l] + ORDER BY [l].[Id] + OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY +) AS [t] +CROSS APPLY ( + SELECT [t1].[Id], [t1].[Name], [t1].[OneToMany_Required_Inverse2Id] AS [Level1Id], [t1].[Level1_Required_Id] AS [Level2Id], [l0].[Id] AS [Id0], [l0].[Date], [l0].[Name] AS [Name0], [l0].[OneToMany_Optional_Self_Inverse1Id], [l0].[OneToMany_Required_Self_Inverse1Id], [l0].[OneToOne_Optional_Self1Id] + FROM ( + SELECT [l1].[Id], [l1].[Level1_Required_Id], [l1].[Name], [l1].[OneToMany_Required_Inverse2Id] + FROM [LevelTwo] AS [l1] + WHERE [t].[Id] = [l1].[OneToMany_Required_Inverse2Id] + ORDER BY [l1].[Id] + OFFSET 1 ROWS FETCH NEXT 3 ROWS ONLY + ) AS [t1] + INNER JOIN [LevelOne] AS [l0] ON [t1].[Level1_Required_Id] = [l0].[Id] +) AS [t0] +ORDER BY [t].[Id], [t0].[Id]"); + } + + public override async Task Multi_level_include_one_to_many_optional_and_one_to_many_optional_produces_valid_sql(bool async) + { + await base.Multi_level_include_one_to_many_optional_and_one_to_many_optional_produces_valid_sql(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Multi_level_include_correct_PK_is_chosen_as_the_join_predicate_for_queries_that_join_same_table_multiple_times(bool async) + { + await base.Multi_level_include_correct_PK_is_chosen_as_the_join_predicate_for_queries_that_join_same_table_multiple_times(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [t].[Id0], [t].[Date], [t].[Level1_Optional_Id], [t].[Level1_Required_Id], [t].[Name0], [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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER 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], [l2].[Id] AS [Id0], [l2].[Date], [l2].[Level1_Optional_Id], [l2].[Level1_Required_Id], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Inverse2Id], [l2].[OneToMany_Optional_Self_Inverse2Id], [l2].[OneToMany_Required_Inverse2Id], [l2].[OneToMany_Required_Self_Inverse2Id], [l2].[OneToOne_Optional_PK_Inverse2Id], [l2].[OneToOne_Optional_Self2Id] + FROM [LevelThree] AS [l1] + INNER JOIN [LevelTwo] AS [l2] ON [l1].[OneToMany_Required_Inverse3Id] = [l2].[Id] +) AS [t] ON [l0].[Id] = [t].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [t].[Id], [t].[Id0]", + // + @"SELECT [l3].[Id], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Name], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Optional_Self_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToMany_Required_Self_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id], [l3].[OneToOne_Optional_Self3Id], [l].[Id], [l0].[Id], [t].[Id], [t].[Id0] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN ( + SELECT [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id], [l2].[Id] AS [Id0] + FROM [LevelThree] AS [l1] + INNER JOIN [LevelTwo] AS [l2] ON [l1].[OneToMany_Required_Inverse3Id] = [l2].[Id] +) AS [t] ON [l0].[Id] = [t].[OneToMany_Optional_Inverse3Id] +INNER JOIN [LevelThree] AS [l3] ON [t].[Id0] = [l3].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [t].[Id], [t].[Id0]"); + } + + public override async Task Multiple_complex_includes(bool async) + { + await base.Multiple_complex_includes(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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN ( + 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], [l2].[Id] AS [Id0], [l2].[Level2_Optional_Id], [l2].[Level2_Required_Id], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Inverse3Id], [l2].[OneToMany_Optional_Self_Inverse3Id], [l2].[OneToMany_Required_Inverse3Id], [l2].[OneToMany_Required_Self_Inverse3Id], [l2].[OneToOne_Optional_PK_Inverse3Id], [l2].[OneToOne_Optional_Self3Id] + FROM [LevelTwo] AS [l1] + LEFT JOIN [LevelThree] AS [l2] ON [l1].[Id] = [l2].[Level2_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Multiple_complex_includes_self_ref(bool async) + { + await base.Multiple_complex_includes_self_ref(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].[Name], [l0].[OneToMany_Optional_Self_Inverse1Id], [l0].[OneToMany_Required_Self_Inverse1Id], [l0].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelOne] AS [l0] ON [l].[OneToOne_Optional_Self1Id] = [l0].[Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"SELECT [l1].[Id], [l1].[Date], [l1].[Name], [l1].[OneToMany_Optional_Self_Inverse1Id], [l1].[OneToMany_Required_Self_Inverse1Id], [l1].[OneToOne_Optional_Self1Id], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelOne] AS [l0] ON [l].[OneToOne_Optional_Self1Id] = [l0].[Id] +INNER JOIN [LevelOne] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Self_Inverse1Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"SELECT [t].[Id], [t].[Date], [t].[Name], [t].[OneToMany_Optional_Self_Inverse1Id], [t].[OneToMany_Required_Self_Inverse1Id], [t].[OneToOne_Optional_Self1Id], [t].[Id0], [t].[Date0], [t].[Name0], [t].[OneToMany_Optional_Self_Inverse1Id0], [t].[OneToMany_Required_Self_Inverse1Id0], [t].[OneToOne_Optional_Self1Id0], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelOne] AS [l0] ON [l].[OneToOne_Optional_Self1Id] = [l0].[Id] +INNER JOIN ( + SELECT [l1].[Id], [l1].[Date], [l1].[Name], [l1].[OneToMany_Optional_Self_Inverse1Id], [l1].[OneToMany_Required_Self_Inverse1Id], [l1].[OneToOne_Optional_Self1Id], [l2].[Id] AS [Id0], [l2].[Date] AS [Date0], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Self_Inverse1Id] AS [OneToMany_Optional_Self_Inverse1Id0], [l2].[OneToMany_Required_Self_Inverse1Id] AS [OneToMany_Required_Self_Inverse1Id0], [l2].[OneToOne_Optional_Self1Id] AS [OneToOne_Optional_Self1Id0] + FROM [LevelOne] AS [l1] + LEFT JOIN [LevelOne] AS [l2] ON [l1].[OneToOne_Optional_Self1Id] = [l2].[Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Self_Inverse1Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Include_reference_and_collection_order_by(bool async) + { + await base.Include_reference_and_collection_order_by(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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Name], [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Name], [l].[Id], [l0].[Id]"); + } + + public override async Task Include_reference_ThenInclude_collection_order_by(bool async) + { + await base.Include_reference_ThenInclude_collection_order_by(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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Name], [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Name], [l].[Id], [l0].[Id]"); + } + + public override async Task Include_collection_then_reference(bool async) + { + await base.Include_collection_then_reference(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY [l].[Id]", + // + @"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], [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], [l].[Id] +FROM [LevelOne] AS [l] +INNER 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] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id]"); + } + + public override async Task Include_collection_with_conditional_order_by(bool async) + { + await base.Include_collection_with_conditional_order_by(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +ORDER BY CASE + WHEN [l].[Name] IS NOT NULL AND ([l].[Name] LIKE N'%03') THEN 1 + ELSE 2 +END, [l].[Id]", + // + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY CASE + WHEN [l].[Name] IS NOT NULL AND ([l].[Name] LIKE N'%03') THEN 1 + ELSE 2 +END, [l].[Id]"); + } + + public override async Task Multiple_complex_include_select(bool async) + { + await base.Multiple_complex_include_select(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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN ( + 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], [l2].[Id] AS [Id0], [l2].[Level2_Optional_Id], [l2].[Level2_Required_Id], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Inverse3Id], [l2].[OneToMany_Optional_Self_Inverse3Id], [l2].[OneToMany_Required_Inverse3Id], [l2].[OneToMany_Required_Self_Inverse3Id], [l2].[OneToOne_Optional_PK_Inverse3Id], [l2].[OneToOne_Optional_Self3Id] + FROM [LevelTwo] AS [l1] + LEFT JOIN [LevelThree] AS [l2] ON [l1].[Id] = [l2].[Level2_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Include_nested_with_optional_navigation(bool async) + { + await base.Include_nested_with_optional_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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +WHERE ([l0].[Name] <> N'L2 09') OR [l0].[Name] IS NULL +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [t].[Id0], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name0], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER 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], [l2].[Id] AS [Id0], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id] + FROM [LevelThree] AS [l1] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Required_Id] +) AS [t] ON [l0].[Id] = [t].[OneToMany_Required_Inverse3Id] +WHERE ([l0].[Name] <> N'L2 09') OR [l0].[Name] IS NULL +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Complex_multi_include_with_order_by_and_paging(bool async) + { + await base.Complex_multi_include_with_order_by_and_paging(async); + + AssertSql( + @"@__p_0='0' +@__p_1='10' + +SELECT [t].[Id], [t].[Date], [t].[Name], [t].[OneToMany_Optional_Self_Inverse1Id], [t].[OneToMany_Required_Self_Inverse1Id], [t].[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] +FROM ( + SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Required_Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id]", + // + @"@__p_0='0' +@__p_1='10' + +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], [t].[Id], [l0].[Id] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Required_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id]", + // + @"@__p_0='0' +@__p_1='10' + +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], [t].[Id], [l0].[Id] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Required_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Required_Inverse3Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id]"); + } + + public override async Task Complex_multi_include_with_order_by_and_paging_joins_on_correct_key(bool async) + { + await base.Complex_multi_include_with_order_by_and_paging_joins_on_correct_key(async); + + AssertSql( + @"@__p_0='0' +@__p_1='10' + +SELECT [t].[Id], [t].[Date], [t].[Name], [t].[OneToMany_Optional_Self_Inverse1Id], [t].[OneToMany_Required_Self_Inverse1Id], [t].[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], [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 ( + SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelTwo] AS [l1] ON [t].[Id] = [l1].[Level1_Required_Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id], [l1].[Id]", + // + @"@__p_0='0' +@__p_1='10' + +SELECT [l2].[Id], [l2].[Level2_Optional_Id], [l2].[Level2_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse3Id], [l2].[OneToMany_Optional_Self_Inverse3Id], [l2].[OneToMany_Required_Inverse3Id], [l2].[OneToMany_Required_Self_Inverse3Id], [l2].[OneToOne_Optional_PK_Inverse3Id], [l2].[OneToOne_Optional_Self3Id], [t].[Id], [l0].[Id], [l1].[Id] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelTwo] AS [l1] ON [t].[Id] = [l1].[Level1_Required_Id] +INNER JOIN [LevelThree] AS [l2] ON [l0].[Id] = [l2].[OneToMany_Optional_Inverse3Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id], [l1].[Id]", + // + @"@__p_0='0' +@__p_1='10' + +SELECT [l2].[Id], [l2].[Level2_Optional_Id], [l2].[Level2_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse3Id], [l2].[OneToMany_Optional_Self_Inverse3Id], [l2].[OneToMany_Required_Inverse3Id], [l2].[OneToMany_Required_Self_Inverse3Id], [l2].[OneToOne_Optional_PK_Inverse3Id], [l2].[OneToOne_Optional_Self3Id], [t].[Id], [l0].[Id], [l1].[Id] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelTwo] AS [l1] ON [t].[Id] = [l1].[Level1_Required_Id] +INNER JOIN [LevelThree] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Required_Inverse3Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id], [l1].[Id]"); + } + + public override async Task Complex_multi_include_with_order_by_and_paging_joins_on_correct_key2(bool async) + { + await base.Complex_multi_include_with_order_by_and_paging_joins_on_correct_key2(async); + + AssertSql( + @"@__p_0='0' +@__p_1='10' + +SELECT [t].[Id], [t].[Date], [t].[Name], [t].[OneToMany_Optional_Self_Inverse1Id], [t].[OneToMany_Required_Self_Inverse1Id], [t].[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], [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 ( + SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id], [l1].[Id]", + // + @"@__p_0='0' +@__p_1='10' + +SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [t].[Id], [l0].[Id], [l1].[Id] +FROM ( + SELECT [l].[Id], [l].[Name] + FROM [LevelOne] AS [l] + ORDER BY [l].[Name] + OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY +) AS [t] +LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +INNER JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Optional_Inverse4Id] +ORDER BY [t].[Name], [t].[Id], [l0].[Id], [l1].[Id]"); + } + + public override async Task Multiple_include_with_multiple_optional_navigations(bool async) + { + await base.Multiple_include_with_multiple_optional_navigations(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], [l1].[Id], [l2].[Id], [l3].[Id], [l4].[Id], [l2].[Level2_Optional_Id], [l2].[Level2_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse3Id], [l2].[OneToMany_Optional_Self_Inverse3Id], [l2].[OneToMany_Required_Inverse3Id], [l2].[OneToMany_Required_Self_Inverse3Id], [l2].[OneToOne_Optional_PK_Inverse3Id], [l2].[OneToOne_Optional_Self3Id], [l3].[Date], [l3].[Level1_Optional_Id], [l3].[Level1_Required_Id], [l3].[Name], [l3].[OneToMany_Optional_Inverse2Id], [l3].[OneToMany_Optional_Self_Inverse2Id], [l3].[OneToMany_Required_Inverse2Id], [l3].[OneToMany_Required_Self_Inverse2Id], [l3].[OneToOne_Optional_PK_Inverse2Id], [l3].[OneToOne_Optional_Self2Id], [l4].[Level2_Optional_Id], [l4].[Level2_Required_Id], [l4].[Name], [l4].[OneToMany_Optional_Inverse3Id], [l4].[OneToMany_Optional_Self_Inverse3Id], [l4].[OneToMany_Required_Inverse3Id], [l4].[OneToMany_Required_Self_Inverse3Id], [l4].[OneToOne_Optional_PK_Inverse3Id], [l4].[OneToOne_Optional_Self3Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] +LEFT JOIN [LevelThree] AS [l2] ON [l0].[Id] = [l2].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l3] ON [l].[Id] = [l3].[Level1_Optional_Id] +LEFT JOIN [LevelThree] AS [l4] ON [l3].[Id] = [l4].[Level2_Optional_Id] +WHERE ([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL +ORDER BY [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [l3].[Id], [l4].[Id]", + // + @"SELECT [l5].[Id], [l5].[Level2_Optional_Id], [l5].[Level2_Required_Id], [l5].[Name], [l5].[OneToMany_Optional_Inverse3Id], [l5].[OneToMany_Optional_Self_Inverse3Id], [l5].[OneToMany_Required_Inverse3Id], [l5].[OneToMany_Required_Self_Inverse3Id], [l5].[OneToOne_Optional_PK_Inverse3Id], [l5].[OneToOne_Optional_Self3Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [l3].[Id], [l4].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] +LEFT JOIN [LevelThree] AS [l2] ON [l0].[Id] = [l2].[Level2_Optional_Id] +LEFT JOIN [LevelTwo] AS [l3] ON [l].[Id] = [l3].[Level1_Optional_Id] +LEFT JOIN [LevelThree] AS [l4] ON [l3].[Id] = [l4].[Level2_Optional_Id] +INNER JOIN [LevelThree] AS [l5] ON [l0].[Id] = [l5].[OneToMany_Optional_Inverse3Id] +WHERE ([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL +ORDER BY [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id], [l3].[Id], [l4].[Id]"); + } + + public override async Task SelectMany_with_Include1(bool async) + { + await base.SelectMany_with_Include1(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Orderby_SelectMany_with_Include1(bool async) + { + await base.Orderby_SelectMany_with_Include1(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task SelectMany_with_Include2(bool async) + { + await base.SelectMany_with_Include2(async); + + AssertSql( + @"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], [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 [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id]"); + } + + public override async Task SelectMany_with_Include_ThenInclude(bool async) + { + await base.SelectMany_with_Include_ThenInclude(async); + + AssertSql( + @"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], [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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]", + // + @"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [l1].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Required_Id] +INNER JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[OneToMany_Optional_Inverse4Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]"); + } + + public override async Task Multiple_SelectMany_with_Include(bool async) + { + await base.Multiple_SelectMany_with_Include(async); + + AssertSql( + @"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], [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Required_Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id]", + // + @"SELECT [l3].[Id], [l3].[Level3_Optional_Id], [l3].[Level3_Required_Id], [l3].[Name], [l3].[OneToMany_Optional_Inverse4Id], [l3].[OneToMany_Optional_Self_Inverse4Id], [l3].[OneToMany_Required_Inverse4Id], [l3].[OneToMany_Required_Self_Inverse4Id], [l3].[OneToOne_Optional_PK_Inverse4Id], [l3].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Required_Id] +INNER JOIN [LevelFour] AS [l3] ON [l1].[Id] = [l3].[OneToMany_Optional_Inverse4Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id], [l2].[Id]"); + } + + public override async Task Required_navigation_with_Include(bool async) + { + await base.Required_navigation_with_Include(async); + + AssertSql(" "); + } + + public override async Task Required_navigation_with_Include_ThenInclude(bool async) + { + await base.Required_navigation_with_Include_ThenInclude(async); + + AssertSql(" "); + } + + public override async Task Optional_navigation_with_Include_ThenInclude(bool async) + { + await base.Optional_navigation_with_Include_ThenInclude(async); + + AssertSql(" "); + } + + public override async Task Multiple_optional_navigation_with_Include(bool async) + { + await base.Multiple_optional_navigation_with_Include(async); + + AssertSql(" "); + } + + public override async Task Multiple_optional_navigation_with_string_based_Include(bool async) + { + await base.Multiple_optional_navigation_with_string_based_Include(async); + + AssertSql(" "); + } + + public override async Task Optional_navigation_with_order_by_and_Include(bool async) + { + await base.Optional_navigation_with_order_by_and_Include(async); + + AssertSql(" "); + } + + public override async Task Optional_navigation_with_Include_and_order(bool async) + { + await base.Optional_navigation_with_Include_and_order(async); + + AssertSql(" "); + } + + public override async Task SelectMany_with_order_by_and_Include(bool async) + { + await base.SelectMany_with_order_by_and_Include(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l0].[Name], [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l0].[Name], [l].[Id], [l0].[Id]"); + } + + public override async Task SelectMany_with_Include_and_order_by(bool async) + { + await base.SelectMany_with_Include_and_order_by(async); + + AssertSql( + @"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], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l0].[Name], [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +INNER JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l0].[Name], [l].[Id], [l0].[Id]"); + } + + public override async Task SelectMany_with_navigation_and_Distinct(bool async) + { + await base.SelectMany_with_navigation_and_Distinct(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] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT DISTINCT [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].[Id]", + // + @"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], [l].[Id], [t].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT DISTINCT [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] +INNER JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id]"); + } + + public override async Task SelectMany_with_navigation_and_Distinct_projecting_columns_including_join_key(bool async) + { + await base.SelectMany_with_navigation_and_Distinct_projecting_columns_including_join_key(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] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT DISTINCT [l0].[Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id] AS [FK] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[FK] +ORDER BY [l].[Id], [t].[Id]", + // + @"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], [l].[Id], [t].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT DISTINCT [l0].[Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id] AS [FK] + FROM [LevelTwo] AS [l0] +) AS [t] ON [l].[Id] = [t].[FK] +INNER JOIN [LevelTwo] AS [l1] ON [l].[Id] = [l1].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_member(bool async) + { + await base.Include_collection_with_multiple_orderbys_member(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY [l].[Name], [l].[Level1_Required_Id], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Name], [l].[Level1_Required_Id], [l].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_property(bool async) + { + await base.Include_collection_with_multiple_orderbys_property(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY [l].[Level1_Required_Id], [l].[Name], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Level1_Required_Id], [l].[Name], [l].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_methodcall(bool async) + { + await base.Include_collection_with_multiple_orderbys_methodcall(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY ABS([l].[Level1_Required_Id]), [l].[Name], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY ABS([l].[Level1_Required_Id]), [l].[Name], [l].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_complex(bool async) + { + await base.Include_collection_with_multiple_orderbys_complex(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY ABS([l].[Level1_Required_Id]) + 7, [l].[Name], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY ABS([l].[Level1_Required_Id]) + 7, [l].[Name], [l].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_complex_repeated(bool async) + { + await base.Include_collection_with_multiple_orderbys_complex_repeated(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY -[l].[Level1_Required_Id], [l].[Name], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY -[l].[Level1_Required_Id], [l].[Name], [l].[Id]"); + } + + public override async Task Include_collection_with_multiple_orderbys_complex_repeated_checked(bool async) + { + await base.Include_collection_with_multiple_orderbys_complex_repeated_checked(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Level1_Optional_Id], [l].[Level1_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse2Id], [l].[OneToMany_Optional_Self_Inverse2Id], [l].[OneToMany_Required_Inverse2Id], [l].[OneToMany_Required_Self_Inverse2Id], [l].[OneToOne_Optional_PK_Inverse2Id], [l].[OneToOne_Optional_Self2Id] +FROM [LevelTwo] AS [l] +ORDER BY -[l].[Level1_Required_Id], [l].[Name], [l].[Id]", + // + @"SELECT [l0].[Id], [l0].[Level2_Optional_Id], [l0].[Level2_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse3Id], [l0].[OneToMany_Optional_Self_Inverse3Id], [l0].[OneToMany_Required_Inverse3Id], [l0].[OneToMany_Required_Self_Inverse3Id], [l0].[OneToOne_Optional_PK_Inverse3Id], [l0].[OneToOne_Optional_Self3Id], [l].[Id] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelThree] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse3Id] +ORDER BY -[l].[Level1_Required_Id], [l].[Name], [l].[Id]"); + } + + public override async Task Include_collection_with_groupby_in_subquery(bool async) + { + await base.Include_collection_with_groupby_in_subquery(async); + + AssertSql(" "); + } + + public override async Task Include_collection_with_groupby_in_subquery_and_filter_before_groupby(bool async) + { + await base.Include_collection_with_groupby_in_subquery_and_filter_before_groupby(async); + + AssertSql(" "); + } + + public override async Task Include_collection_with_groupby_in_subquery_and_filter_after_groupby(bool async) + { + await base.Include_collection_with_groupby_in_subquery_and_filter_after_groupby(async); + + AssertSql(" "); + } + + public override async Task Include_reference_collection_order_by_reference_navigation(bool async) + { + await base.Include_reference_collection_order_by_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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +ORDER BY [l0].[Id], [l].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l0].[Id], [l].[Id]"); + } + + public override async Task Include_after_SelectMany_and_reference_navigation(bool async) + { + await base.Include_after_SelectMany_and_reference_navigation(async); + + AssertSql(" "); + } + + public override async Task Include_after_multiple_SelectMany_and_reference_navigation(bool async) + { + await base.Include_after_multiple_SelectMany_and_reference_navigation(async); + + AssertSql(" "); + } + + public override async Task Include_after_SelectMany_and_multiple_reference_navigations(bool async) + { + await base.Include_after_SelectMany_and_multiple_reference_navigations(async); + + AssertSql(" "); + } + + public override async Task Include_after_SelectMany_and_reference_navigation_with_another_SelectMany_with_Distinct(bool async) + { + await base.Include_after_SelectMany_and_reference_navigation_with_another_SelectMany_with_Distinct(async); + + AssertSql(" "); + } + + public override void Include15() + { + base.Include15(); + + AssertSql(" "); + } + + public override void Include16() + { + base.Include16(); + + AssertSql(" "); + } + + public override void IncludeCollection1() + { + base.IncludeCollection1(); + + 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] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override void IncludeCollection2() + { + base.IncludeCollection2(); + + 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] +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] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0]"); + } + + public override void IncludeCollection3() + { + base.IncludeCollection3(); + + 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], [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 [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Optional_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]"); + } + + public override void IncludeCollection4() + { + base.IncludeCollection4(); + + AssertSql( + @"SELECT [l].[Id], [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 [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override void IncludeCollection5() + { + base.IncludeCollection5(); + + AssertSql( + @"SELECT [l].[Id], [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] +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] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0]"); + } + + public override void IncludeCollection6() + { + base.IncludeCollection6(); + + AssertSql( + @"SELECT [l].[Id], [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], [t].[Id1], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name1], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id] +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], [l2].[Id] AS [Id1], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name1], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0], [t].[Id1]"); + } + + public override void IncludeCollection6_1() + { + base.IncludeCollection6_1(); + + 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], [t].[Id1], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name1], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id] +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], [l2].[Id] AS [Id1], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name1], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0], [t].[Id1]"); + } + + public override void IncludeCollection6_2() + { + base.IncludeCollection6_2(); + + AssertSql( + @"SELECT [l].[Id], [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], [t].[Id1], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name1], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id], [t].[Id2], [t].[Level2_Optional_Id0], [t].[Level2_Required_Id0], [t].[Name2], [t].[OneToMany_Optional_Inverse3Id0], [t].[OneToMany_Optional_Self_Inverse3Id0], [t].[OneToMany_Required_Inverse3Id0], [t].[OneToMany_Required_Self_Inverse3Id0], [t].[OneToOne_Optional_PK_Inverse3Id0], [t].[OneToOne_Optional_Self3Id0], [t].[Id3], [t].[Level3_Optional_Id0], [t].[Level3_Required_Id0], [t].[Name3], [t].[OneToMany_Optional_Inverse4Id0], [t].[OneToMany_Optional_Self_Inverse4Id0], [t].[OneToMany_Required_Inverse4Id0], [t].[OneToMany_Required_Self_Inverse4Id0], [t].[OneToOne_Optional_PK_Inverse4Id0], [t].[OneToOne_Optional_Self4Id0] +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], [l2].[Id] AS [Id1], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name1], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l3].[Id] AS [Id2], [l3].[Level2_Optional_Id] AS [Level2_Optional_Id0], [l3].[Level2_Required_Id] AS [Level2_Required_Id0], [l3].[Name] AS [Name2], [l3].[OneToMany_Optional_Inverse3Id] AS [OneToMany_Optional_Inverse3Id0], [l3].[OneToMany_Optional_Self_Inverse3Id] AS [OneToMany_Optional_Self_Inverse3Id0], [l3].[OneToMany_Required_Inverse3Id] AS [OneToMany_Required_Inverse3Id0], [l3].[OneToMany_Required_Self_Inverse3Id] AS [OneToMany_Required_Self_Inverse3Id0], [l3].[OneToOne_Optional_PK_Inverse3Id] AS [OneToOne_Optional_PK_Inverse3Id0], [l3].[OneToOne_Optional_Self3Id] AS [OneToOne_Optional_Self3Id0], [l4].[Id] AS [Id3], [l4].[Level3_Optional_Id] AS [Level3_Optional_Id0], [l4].[Level3_Required_Id] AS [Level3_Required_Id0], [l4].[Name] AS [Name3], [l4].[OneToMany_Optional_Inverse4Id] AS [OneToMany_Optional_Inverse4Id0], [l4].[OneToMany_Optional_Self_Inverse4Id] AS [OneToMany_Optional_Self_Inverse4Id0], [l4].[OneToMany_Required_Inverse4Id] AS [OneToMany_Required_Inverse4Id0], [l4].[OneToMany_Required_Self_Inverse4Id] AS [OneToMany_Required_Self_Inverse4Id0], [l4].[OneToOne_Optional_PK_Inverse4Id] AS [OneToOne_Optional_PK_Inverse4Id0], [l4].[OneToOne_Optional_Self4Id] AS [OneToOne_Optional_Self4Id0] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Optional_Id] + LEFT JOIN [LevelThree] AS [l3] ON [l0].[Id] = [l3].[Level2_Optional_Id] + LEFT JOIN [LevelFour] AS [l4] ON [l3].[Id] = [l4].[OneToMany_Optional_Inverse4Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t].[Id3]"); + } + + public override void IncludeCollection6_3() + { + base.IncludeCollection6_3(); + + 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], [t].[Id1], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name1], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id], [t].[Id2], [t].[Level2_Optional_Id0], [t].[Level2_Required_Id0], [t].[Name2], [t].[OneToMany_Optional_Inverse3Id0], [t].[OneToMany_Optional_Self_Inverse3Id0], [t].[OneToMany_Required_Inverse3Id0], [t].[OneToMany_Required_Self_Inverse3Id0], [t].[OneToOne_Optional_PK_Inverse3Id0], [t].[OneToOne_Optional_Self3Id0], [t].[Id3], [t].[Level3_Optional_Id0], [t].[Level3_Required_Id0], [t].[Name3], [t].[OneToMany_Optional_Inverse4Id0], [t].[OneToMany_Optional_Self_Inverse4Id0], [t].[OneToMany_Required_Inverse4Id0], [t].[OneToMany_Required_Self_Inverse4Id0], [t].[OneToOne_Optional_PK_Inverse4Id0], [t].[OneToOne_Optional_Self4Id0] +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], [l2].[Id] AS [Id1], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name1], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l3].[Id] AS [Id2], [l3].[Level2_Optional_Id] AS [Level2_Optional_Id0], [l3].[Level2_Required_Id] AS [Level2_Required_Id0], [l3].[Name] AS [Name2], [l3].[OneToMany_Optional_Inverse3Id] AS [OneToMany_Optional_Inverse3Id0], [l3].[OneToMany_Optional_Self_Inverse3Id] AS [OneToMany_Optional_Self_Inverse3Id0], [l3].[OneToMany_Required_Inverse3Id] AS [OneToMany_Required_Inverse3Id0], [l3].[OneToMany_Required_Self_Inverse3Id] AS [OneToMany_Required_Self_Inverse3Id0], [l3].[OneToOne_Optional_PK_Inverse3Id] AS [OneToOne_Optional_PK_Inverse3Id0], [l3].[OneToOne_Optional_Self3Id] AS [OneToOne_Optional_Self3Id0], [l4].[Id] AS [Id3], [l4].[Level3_Optional_Id] AS [Level3_Optional_Id0], [l4].[Level3_Required_Id] AS [Level3_Required_Id0], [l4].[Name] AS [Name3], [l4].[OneToMany_Optional_Inverse4Id] AS [OneToMany_Optional_Inverse4Id0], [l4].[OneToMany_Optional_Self_Inverse4Id] AS [OneToMany_Optional_Self_Inverse4Id0], [l4].[OneToMany_Required_Inverse4Id] AS [OneToMany_Required_Inverse4Id0], [l4].[OneToMany_Required_Self_Inverse4Id] AS [OneToMany_Required_Self_Inverse4Id0], [l4].[OneToOne_Optional_PK_Inverse4Id] AS [OneToOne_Optional_PK_Inverse4Id0], [l4].[OneToOne_Optional_Self4Id] AS [OneToOne_Optional_Self4Id0] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Optional_Id] + LEFT JOIN [LevelThree] AS [l3] ON [l0].[Id] = [l3].[Level2_Optional_Id] + LEFT JOIN [LevelFour] AS [l4] ON [l3].[Id] = [l4].[OneToMany_Optional_Inverse4Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0], [t].[Id1], [t].[Id2], [t].[Id3]"); + } + + public override void IncludeCollection6_4() + { + base.IncludeCollection6_4(); + + AssertSql( + @"SELECT [l].[Id], [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], [t].[Id0], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name0], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id], [t].[Id1] +FROM [LevelOne] AS [l] +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], [l2].[Id] AS [Id0], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name] AS [Name0], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l0].[Id] AS [Id1], [l0].[OneToMany_Optional_Inverse2Id] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l2] ON [l1].[Id] = [l2].[Level3_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id1], [t].[Id], [t].[Id0]"); + } + + public override void IncludeCollection7() + { + base.IncludeCollection7(); + + 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], [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] + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +LEFT JOIN ( + SELECT [l2].[Id], [l2].[Date], [l2].[Level1_Optional_Id], [l2].[Level1_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse2Id], [l2].[OneToMany_Optional_Self_Inverse2Id], [l2].[OneToMany_Required_Inverse2Id], [l2].[OneToMany_Required_Self_Inverse2Id], [l2].[OneToOne_Optional_PK_Inverse2Id], [l2].[OneToOne_Optional_Self2Id], [l3].[Id] AS [Id0], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Name] AS [Name0], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Optional_Self_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToMany_Required_Self_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id], [l3].[OneToOne_Optional_Self3Id] + FROM [LevelTwo] AS [l2] + LEFT JOIN [LevelThree] AS [l3] ON [l2].[Id] = [l3].[OneToOne_Optional_PK_Inverse3Id] +) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id] +ORDER BY [l].[Id], [t].[Id], [t].[Id0], [t0].[Id], [t0].[Id0]"); + } + + public override async Task IncludeCollection8(bool async) + { + await base.IncludeCollection8(async); + + AssertSql( + @"SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] +FROM [LevelOne] AS [l] +WHERE ( + SELECT COUNT(*) + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL)) > 0 +ORDER BY [l].[Id]", + // + @"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], [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], [t].[Id1], [t].[Level3_Optional_Id], [t].[Level3_Required_Id], [t].[Name1], [t].[OneToMany_Optional_Inverse4Id], [t].[OneToMany_Optional_Self_Inverse4Id], [t].[OneToMany_Required_Inverse4Id], [t].[OneToMany_Required_Self_Inverse4Id], [t].[OneToOne_Optional_PK_Inverse4Id], [t].[OneToOne_Optional_Self4Id], [l].[Id] +FROM [LevelOne] AS [l] +INNER JOIN ( + SELECT [l2].[Id], [l2].[Date], [l2].[Level1_Optional_Id], [l2].[Level1_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse2Id], [l2].[OneToMany_Optional_Self_Inverse2Id], [l2].[OneToMany_Required_Inverse2Id], [l2].[OneToMany_Required_Self_Inverse2Id], [l2].[OneToOne_Optional_PK_Inverse2Id], [l2].[OneToOne_Optional_Self2Id], [l3].[Id] AS [Id0], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Name] AS [Name0], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Optional_Self_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToMany_Required_Self_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id], [l3].[OneToOne_Optional_Self3Id], [l4].[Id] AS [Id1], [l4].[Level3_Optional_Id], [l4].[Level3_Required_Id], [l4].[Name] AS [Name1], [l4].[OneToMany_Optional_Inverse4Id], [l4].[OneToMany_Optional_Self_Inverse4Id], [l4].[OneToMany_Required_Inverse4Id], [l4].[OneToMany_Required_Self_Inverse4Id], [l4].[OneToOne_Optional_PK_Inverse4Id], [l4].[OneToOne_Optional_Self4Id] + FROM [LevelTwo] AS [l2] + LEFT JOIN [LevelThree] AS [l3] ON [l2].[Id] = [l3].[OneToOne_Optional_PK_Inverse3Id] + LEFT JOIN [LevelFour] AS [l4] ON [l3].[Id] = [l4].[Level3_Optional_Id] +) AS [t] ON [l].[Id] = [t].[OneToMany_Optional_Inverse2Id] +WHERE ( + SELECT COUNT(*) + FROM [LevelTwo] AS [l0] + LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToOne_Optional_PK_Inverse3Id] + WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l1].[Name] <> N'Foo') OR [l1].[Name] IS NULL)) > 0 +ORDER BY [l].[Id]"); + } + + public override async Task Including_reference_navigation_and_projecting_collection_navigation(bool async) + { + await base.Including_reference_navigation_and_projecting_collection_navigation(async); + + AssertSql( + @"SELECT [l].[Id], [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], [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 [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]", + // + @"SELECT [l2].[Id], [l2].[Date], [l2].[Level1_Optional_Id], [l2].[Level1_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse2Id], [l2].[OneToMany_Optional_Self_Inverse2Id], [l2].[OneToMany_Required_Inverse2Id], [l2].[OneToMany_Required_Self_Inverse2Id], [l2].[OneToOne_Optional_PK_Inverse2Id], [l2].[OneToOne_Optional_Self2Id], [l].[Id], [l0].[Id], [l1].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +LEFT JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[Level2_Optional_Id] +INNER JOIN [LevelTwo] AS [l2] ON [l].[Id] = [l2].[OneToMany_Required_Inverse2Id] +ORDER BY [l].[Id], [l0].[Id], [l1].[Id]"); + } + + public override async Task LeftJoin_with_Any_on_outer_source_and_projecting_collection_from_inner(bool async) + { + await base.LeftJoin_with_Any_on_outer_source_and_projecting_collection_from_inner(async); + + AssertSql( + @"SELECT CASE + WHEN [l0].[Id] IS NULL THEN 0 + ELSE [l0].[Id] +END, [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +WHERE [l].[Name] IN (N'L1 01', N'L1 02') +ORDER BY [l].[Id], [l0].[Id]", + // + @"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], [l].[Id], [l0].[Id] +FROM [LevelOne] AS [l] +LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] +INNER JOIN [LevelThree] AS [l1] ON [l0].[Id] = [l1].[OneToMany_Required_Inverse3Id] +WHERE [l].[Name] IN (N'L1 01', N'L1 02') +ORDER BY [l].[Id], [l0].[Id]"); + } + + public override async Task Filtered_include_different_filter_set_on_same_navigation_twice(bool async) + { + await base.Filtered_include_different_filter_set_on_same_navigation_twice(async); + + AssertSql( + ); + } + + public override async Task Filtered_include_different_filter_set_on_same_navigation_twice_multi_level(bool async) + { + await base.Filtered_include_different_filter_set_on_same_navigation_twice_multi_level(async); + + AssertSql( + ); + } + + public override async Task Filtered_include_include_parameter_used_inside_filter_throws(bool async) + { + await base.Filtered_include_include_parameter_used_inside_filter_throws(async); + + AssertSql( + ); + } + + public override void Filtered_include_is_considered_loaded() + { + base.Filtered_include_is_considered_loaded(); + + AssertSql( + @"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] +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].[OneToMany_Optional_Inverse2Id], [t0].[Id]"); + } + + public override async Task Filtered_include_with_Distinct_throws(bool async) + { + await base.Filtered_include_with_Distinct_throws(async); + + AssertSql( + ); + } + + public override async Task Filtered_include_calling_methods_directly_on_parameter_throws(bool async) + { + await base.Filtered_include_calling_methods_directly_on_parameter_throws(async); + + AssertSql( + ); + } + + public override async Task Projecting_collection_with_FirstOrDefault(bool async) + { + await base.Projecting_collection_with_FirstOrDefault(async); + + AssertSql( + @"SELECT [t].[Id] +FROM ( + SELECT TOP(1) [l].[Id] + FROM [LevelOne] AS [l] + WHERE [l].[Id] = 1 +) AS [t] +ORDER BY [t].[Id]", + // + @"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] +FROM ( + SELECT TOP(1) [l].[Id] + FROM [LevelOne] AS [l] + WHERE [l].[Id] = 1 +) AS [t] +INNER JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[OneToMany_Optional_Inverse2Id] +ORDER BY [t].[Id]"); } private void AssertSql(params string[] expected) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index 13741ba9a59..83fc95683f0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -3486,21 +3486,6 @@ ELSE [l1].[Name] END IS NULL"); } - public override async Task Projecting_collection_with_FirstOrDefault_without_split_works(bool async) - { - await base.Projecting_collection_with_FirstOrDefault_without_split_works(async); - - AssertSql( - @"SELECT [t].[Id], [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 ( - SELECT TOP(1) [l].[Id] - FROM [LevelOne] AS [l] - WHERE [l].[Id] = 1 -) AS [t] -LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[OneToMany_Optional_Inverse2Id] -ORDER BY [t].[Id], [l0].[Id]"); - } - public override async Task Distinct_skip_without_orderby(bool async) { await base.Distinct_skip_without_orderby(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs index f6713f07a3b..f5fe202058a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs @@ -984,7 +984,7 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t].[Id], [t].[Discriminator], [t].[Name], [t].[Number], [t].[IsGreen], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [e0].[Id], [e0].[Discriminator], [e0].[Name], [e0].[Number], [e0].[IsGreen] + SELECT [e0].[Id], [e0].[Discriminator], [e0].[Name], [e0].[Number], [e0].[IsGreen], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN [EntityRoots] AS [e0] ON [j].[RootId] = [e0].[Id] ) AS [t] ON (([e].[Key1] = [t].[CompositeId1]) AND ([e].[Key2] = [t].[CompositeId2])) AND ([e].[Key3] = [t].[CompositeId3]) @@ -1003,7 +1003,7 @@ FROM [EntityTwos] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[TwoId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1023,7 +1023,7 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t0].[Id], [t0].[Discriminator], [t0].[Name], [t0].[Number], [t0].[IsGreen], [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[LeafId] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [t].[Id], [t].[Discriminator], [t].[Name], [t].[Number], [t].[IsGreen] + SELECT [t].[Id], [t].[Discriminator], [t].[Name], [t].[Number], [t].[IsGreen], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN ( SELECT [e0].[Id], [e0].[Discriminator], [e0].[Name], [e0].[Number], [e0].[IsGreen] @@ -1036,7 +1036,7 @@ FROM [EntityRoots] AS [e0] @"SELECT [t1].[Id], [t1].[Name], [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[LeafId], [t0].[Id] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [t].[Id] + SELECT [t].[Id], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN ( SELECT [e0].[Id] @@ -1045,7 +1045,7 @@ FROM [EntityRoots] AS [e0] ) AS [t] ON [j].[LeafId] = [t].[Id] ) AS [t0] ON (([e].[Key1] = [t0].[CompositeId1]) AND ([e].[Key2] = [t0].[CompositeId2])) AND ([e].[Key3] = [t0].[CompositeId3]) INNER JOIN ( - SELECT [j0].[EntityBranchId], [e1].[Id], [e1].[Name] + SELECT [e1].[Id], [e1].[Name], [j0].[EntityBranchId] FROM [JoinOneToBranch] AS [j0] INNER JOIN [EntityOnes] AS [e1] ON [j0].[EntityOneId] = [e1].[Id] ) AS [t1] ON [t0].[Id] = [t1].[EntityBranchId] @@ -1064,7 +1064,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1074,13 +1074,13 @@ FROM [JoinOneToThreePayloadFull] AS [j] @"SELECT [t0].[Id], [t0].[Name], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id], [t].[Id0] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e1].[Id] AS [Id0] + SELECT [e0].[Id], [e1].[Id] AS [Id0], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [j0].[LeftId], [e2].[Id], [e2].[Name] + SELECT [e2].[Id], [e2].[Name], [j0].[LeftId] FROM [JoinOneSelfPayload] AS [j0] INNER JOIN [EntityOnes] AS [e2] ON [j0].[RightId] = [e2].[Id] ) AS [t0] ON [t].[Id] = [t0].[LeftId] @@ -1101,7 +1101,7 @@ FROM [EntityTwos] AS [e] FROM [EntityTwos] AS [e] LEFT JOIN [EntityThrees] AS [e0] ON [e].[Id] = [e0].[ReferenceInverseId] INNER JOIN ( - SELECT [e1].[EntityTwoId], [e2].[Id], [e2].[Name] + SELECT [e2].[Id], [e2].[Name], [e1].[EntityTwoId] FROM [EntityOneEntityTwo] AS [e1] INNER JOIN [EntityOnes] AS [e2] ON [e1].[EntityOneId] = [e2].[Id] ) AS [t] ON [e].[Id] = [t].[EntityTwoId] @@ -1120,7 +1120,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[ThreeId] FROM [JoinOneToThreePayloadFullShared] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1137,18 +1137,14 @@ public override async Task Filtered_include_skip_navigation_order_by_split(bool FROM [EntityThrees] AS [e] ORDER BY [e].[Id]", // - @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] + @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [t].[ThreeId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] - FROM ( - SELECT [j].[ThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[ThreeId] ORDER BY [e0].[Id]) AS [row] - FROM [JoinTwoToThree] AS [j] - INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [e].[Id] = [t0].[ThreeId] -ORDER BY [e].[Id], [t0].[ThreeId], [t0].[Id]"); + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[ThreeId] + FROM [JoinTwoToThree] AS [j] + INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_skip_split(bool async) @@ -1163,9 +1159,9 @@ FROM [EntityTwos] AS [e] @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [t].[LeftId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[LeftId] FROM ( - SELECT [j].[LeftId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[LeftId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[LeftId], ROW_NUMBER() OVER(PARTITION BY [j].[LeftId] ORDER BY [e0].[Id]) AS [row] FROM [JoinTwoSelfShared] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[RightId] = [e0].[Id] ) AS [t] @@ -1186,9 +1182,9 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3] FROM ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] FROM [JoinTwoToCompositeKeyShared] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] @@ -1206,18 +1202,18 @@ public override async Task Filtered_include_skip_navigation_order_by_skip_take_s FROM [EntityCompositeKeys] AS [e] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3]", // - @"SELECT [t0].[Id0], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] + @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[Id0], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3] FROM ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [e0].[Id] AS [Id0], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] FROM [JoinThreeToCompositeKeyFull] AS [j] INNER JOIN [EntityThrees] AS [e0] ON [j].[ThreeId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON (([e].[Key1] = [t0].[CompositeId1]) AND ([e].[Key2] = [t0].[CompositeId2])) AND ([e].[Key3] = [t0].[CompositeId3]) -ORDER BY [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id0]"); +ORDER BY [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id]"); } public override async Task Filtered_then_include_skip_navigation_where_split(bool async) @@ -1232,7 +1228,7 @@ FROM [EntityRoots] AS [e] @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [e].[Id], [t].[EntityRootId], [t].[EntityThreeId] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [e0].[EntityRootId], [e0].[EntityThreeId] FROM [EntityRootEntityThree] AS [e0] INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] ) AS [t] ON [e].[Id] = [t].[EntityRootId] @@ -1241,12 +1237,12 @@ FROM [EntityRootEntityThree] AS [e0] @"SELECT [t0].[Id], [t0].[Name], [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id] + SELECT [e1].[Id], [e0].[EntityRootId], [e0].[EntityThreeId] FROM [EntityRootEntityThree] AS [e0] INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] ) AS [t] ON [e].[Id] = [t].[EntityRootId] INNER JOIN ( - SELECT [j].[ThreeId], [e2].[Id], [e2].[Name] + SELECT [e2].[Id], [e2].[Name], [j].[ThreeId] FROM [JoinOneToThreePayloadFullShared] AS [j] INNER JOIN [EntityOnes] AS [e2] ON [j].[OneId] = [e2].[Id] WHERE [e2].[Id] < 10 @@ -1266,29 +1262,29 @@ FROM [EntityRoots] AS [e] @"SELECT [t].[Key1], [t].[Key2], [t].[Key3], [t].[Name], [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId], [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name] + SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN [EntityCompositeKeys] AS [e0] ON (([j].[CompositeId1] = [e0].[Key1]) AND ([j].[CompositeId2] = [e0].[Key2])) AND ([j].[CompositeId3] = [e0].[Key3]) ) AS [t] ON [e].[Id] = [t].[RootId] ORDER BY [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3]", // - @"SELECT [t0].[Id0], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3] + @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId], [e0].[Key1], [e0].[Key2], [e0].[Key3] + SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN [EntityCompositeKeys] AS [e0] ON (([j].[CompositeId1] = [e0].[Key1]) AND ([j].[CompositeId2] = [e0].[Key2])) AND ([j].[CompositeId3] = [e0].[Key3]) ) AS [t] ON [e].[Id] = [t].[RootId] INNER JOIN ( - SELECT [t1].[CompositeId1], [t1].[CompositeId2], [t1].[CompositeId3], [t1].[Id0], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[CompositeId1], [t1].[CompositeId2], [t1].[CompositeId3] FROM ( - SELECT [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] ORDER BY [e1].[Id]) AS [row] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] ORDER BY [e1].[Id]) AS [row] FROM [JoinThreeToCompositeKeyFull] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] ) AS [t1] WHERE (1 < [t1].[row]) AND ([t1].[row] <= 3) ) AS [t0] ON (([t].[Key1] = [t0].[CompositeId1]) AND ([t].[Key2] = [t0].[CompositeId2])) AND ([t].[Key3] = [t0].[CompositeId3]) -ORDER BY [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id0]"); +ORDER BY [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_split(bool async) @@ -1304,7 +1300,7 @@ FROM [EntityRoots] AS [e] @"SELECT [t].[Key1], [t].[Key2], [t].[Key3], [t].[Name], [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[LeafId] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name] + SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN [EntityCompositeKeys] AS [e0] ON (([j].[CompositeId1] = [e0].[Key1]) AND ([j].[CompositeId2] = [e0].[Key2])) AND ([j].[CompositeId3] = [e0].[Key3]) WHERE [e0].[Key1] < 5 @@ -1315,13 +1311,13 @@ WHERE [e0].[Key1] < 5 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[LeafId], [t].[Key1], [t].[Key2], [t].[Key3] FROM [EntityRoots] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [e0].[Key1], [e0].[Key2], [e0].[Key3] + SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN [EntityCompositeKeys] AS [e0] ON (([j].[CompositeId1] = [e0].[Key1]) AND ([j].[CompositeId2] = [e0].[Key2])) AND ([j].[CompositeId3] = [e0].[Key3]) WHERE [e0].[Key1] < 5 ) AS [t] ON [e].[Id] = [t].[LeafId] INNER JOIN ( - SELECT [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] FROM [JoinTwoToCompositeKeyShared] AS [j0] INNER JOIN [EntityTwos] AS [e1] ON [j0].[TwoId] = [e1].[Id] ) AS [t0] ON (([t].[Key1] = [t0].[CompositeId1]) AND ([t].[Key2] = [t0].[CompositeId2])) AND ([t].[Key3] = [t0].[CompositeId3]) @@ -1334,41 +1330,41 @@ public override async Task Filtered_include_skip_navigation_order_by_skip_take_t await base.Filtered_include_skip_navigation_order_by_skip_take_then_include_skip_navigation_where_split(async); AssertSql( - @"SELECT [e].[Id], [e].[Name] + @"SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] ORDER BY [e].[Id]", - // - @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId] + // + @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [t].[OneId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[OneId], [t].[TwoId] FROM ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[OneId], [j].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]", - // - @"SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id] +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]", + // + @"SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [t].[OneId], [t].[TwoId], [t].[Id] + SELECT [t].[Id], [t].[OneId], [t].[TwoId] FROM ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [j].[OneId], [j].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] INNER JOIN ( - SELECT [j0].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[TwoId] FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 10 ) AS [t1] ON [t0].[Id] = [t1].[TwoId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]"); +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_order_by_skip_take_split(bool async) @@ -1383,7 +1379,7 @@ FROM [EntityOnes] AS [e] @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1393,15 +1389,15 @@ WHERE [e0].[Id] < 10 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId], [t].[Id] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[OneId] INNER JOIN ( - SELECT [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[TwoId] FROM ( - SELECT [j0].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[TwoId] ORDER BY [e1].[Id]) AS [row] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j0].[TwoId] ORDER BY [e1].[Id]) AS [row] FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] ) AS [t1] @@ -1422,7 +1418,7 @@ FROM [EntityTwos] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1433,7 +1429,7 @@ WHERE [e0].[Id] < 10 @"SELECT [e2].[Id], [e2].[CollectionInverseId], [e2].[ExtraId], [e2].[Name], [e2].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId], [t].[Id], [t].[Id0] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e1].[Id] AS [Id0] + SELECT [e0].[Id], [e1].[Id] AS [Id0], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1455,7 +1451,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1465,15 +1461,15 @@ WHERE [e0].[Id] < 10 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [t1].[OneId], [t1].[Id], [t1].[CollectionInverseId], [t1].[ExtraId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[ExtraId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[OneId] FROM ( - SELECT [j0].[OneId], [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[OneId] ORDER BY [e1].[Id]) AS [row] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[OneId], ROW_NUMBER() OVER(PARTITION BY [j0].[OneId] ORDER BY [e1].[Id]) AS [row] FROM [JoinOneToTwo] AS [j0] INNER JOIN [EntityTwos] AS [e1] ON [j0].[TwoId] = [e1].[Id] ) AS [t1] @@ -1484,13 +1480,13 @@ FROM [JoinOneToTwo] AS [j0] @"SELECT [t0].[Id], [t0].[Discriminator], [t0].[Name], [t0].[Number], [t0].[IsGreen], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [j0].[EntityOneId], [t1].[Id], [t1].[Discriminator], [t1].[Name], [t1].[Number], [t1].[IsGreen] + SELECT [t1].[Id], [t1].[Discriminator], [t1].[Name], [t1].[Number], [t1].[IsGreen], [j0].[EntityOneId] FROM [JoinOneToBranch] AS [j0] INNER JOIN ( SELECT [e1].[Id], [e1].[Discriminator], [e1].[Name], [e1].[Number], [e1].[IsGreen] @@ -1514,7 +1510,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] > 15 @@ -1524,7 +1520,7 @@ WHERE [e0].[Id] > 15 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] > 15 @@ -1563,7 +1559,7 @@ FROM [EntityTwos] AS [e0] WHERE [e0].[Id] > 15 ) AS [t] ON [e].[Id] = [t].[CollectionInverseId] INNER JOIN ( - SELECT [j].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j].[TwoId] FROM [JoinTwoToThree] AS [j] INNER JOIN [EntityThrees] AS [e1] ON [j].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 5 diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs index eee2ea7f3fc..41deb3b0cbd 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs @@ -1136,18 +1136,14 @@ public override async Task Filtered_include_skip_navigation_order_by_split(bool FROM [EntityThrees] AS [e] ORDER BY [e].[Id]", // - @"SELECT [t0].[ThreeId], [t0].[TwoId], [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] + @"SELECT [t].[ThreeId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [t].[ThreeId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] - FROM ( - SELECT [j].[ThreeId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[ThreeId] ORDER BY [e0].[Id]) AS [row] - FROM [JoinTwoToThree] AS [j] - INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [e].[Id] = [t0].[ThreeId] -ORDER BY [e].[Id], [t0].[ThreeId], [t0].[Id]"); + SELECT [j].[ThreeId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId] + FROM [JoinTwoToThree] AS [j] + INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_skip_split(bool async) @@ -1348,7 +1344,7 @@ FROM [JoinOneToTwo] AS [j] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]", +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]", // @"SELECT [t1].[ThreeId], [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id] FROM [EntityOnes] AS [e] @@ -1367,7 +1363,7 @@ FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 10 ) AS [t1] ON [t0].[Id] = [t1].[TwoId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]"); +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_order_by_skip_take_split(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSplitIncludeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSplitIncludeQuerySqlServerTest.cs index 4d9724ddde2..7156635ce24 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSplitIncludeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSplitIncludeQuerySqlServerTest.cs @@ -1702,7 +1702,7 @@ public override async Task Multi_level_includes_are_applied_with_skip(bool async AssertSql( @"@__p_0='1' -SELECT [t].[CustomerID], [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[OrderID0], [t0].[ProductID], [t0].[Discount], [t0].[Quantity], [t0].[UnitPrice] +SELECT [t].[CustomerID] FROM ( SELECT [c].[CustomerID] FROM [Customers] AS [c] @@ -1710,12 +1710,34 @@ WHERE [c].[CustomerID] LIKE N'A%' ORDER BY [c].[CustomerID] OFFSET @__p_0 ROWS FETCH NEXT 1 ROWS ONLY ) AS [t] -LEFT JOIN ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o0].[OrderID] AS [OrderID0], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice] - FROM [Orders] AS [o] - LEFT JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] -) AS [t0] ON [t].[CustomerID] = [t0].[CustomerID] -ORDER BY [t].[CustomerID], [t0].[OrderID], [t0].[OrderID0], [t0].[ProductID]"); +ORDER BY [t].[CustomerID]", + // + @"@__p_0='1' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [t].[CustomerID] +FROM ( + SELECT [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + OFFSET @__p_0 ROWS FETCH NEXT 1 ROWS ONLY +) AS [t] +INNER JOIN [Orders] AS [o] ON [t].[CustomerID] = [o].[CustomerID] +ORDER BY [t].[CustomerID], [o].[OrderID]", + // + @"@__p_0='1' + +SELECT [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice], [t].[CustomerID], [o].[OrderID] +FROM ( + SELECT [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + OFFSET @__p_0 ROWS FETCH NEXT 1 ROWS ONLY +) AS [t] +INNER JOIN [Orders] AS [o] ON [t].[CustomerID] = [o].[CustomerID] +INNER JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] +ORDER BY [t].[CustomerID], [o].[OrderID]"); } public override async Task Multi_level_includes_are_applied_with_take(bool async) @@ -1725,7 +1747,7 @@ public override async Task Multi_level_includes_are_applied_with_take(bool async AssertSql( @"@__p_0='1' -SELECT [t0].[CustomerID], [t1].[OrderID], [t1].[CustomerID], [t1].[EmployeeID], [t1].[OrderDate], [t1].[OrderID0], [t1].[ProductID], [t1].[Discount], [t1].[Quantity], [t1].[UnitPrice] +SELECT [t0].[CustomerID] FROM ( SELECT TOP(1) [t].[CustomerID] FROM ( @@ -1736,12 +1758,40 @@ ORDER BY [c].[CustomerID] ) AS [t] ORDER BY [t].[CustomerID] ) AS [t0] -LEFT JOIN ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o0].[OrderID] AS [OrderID0], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice] - FROM [Orders] AS [o] - LEFT JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] -) AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID] -ORDER BY [t0].[CustomerID], [t1].[OrderID], [t1].[OrderID0], [t1].[ProductID]"); +ORDER BY [t0].[CustomerID]", + // + @"@__p_0='1' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [t0].[CustomerID] +FROM ( + SELECT TOP(1) [t].[CustomerID] + FROM ( + SELECT TOP(@__p_0) [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + ) AS [t] + ORDER BY [t].[CustomerID] +) AS [t0] +INNER JOIN [Orders] AS [o] ON [t0].[CustomerID] = [o].[CustomerID] +ORDER BY [t0].[CustomerID], [o].[OrderID]", + // + @"@__p_0='1' + +SELECT [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice], [t0].[CustomerID], [o].[OrderID] +FROM ( + SELECT TOP(1) [t].[CustomerID] + FROM ( + SELECT TOP(@__p_0) [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + ) AS [t] + ORDER BY [t].[CustomerID] +) AS [t0] +INNER JOIN [Orders] AS [o] ON [t0].[CustomerID] = [o].[CustomerID] +INNER JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] +ORDER BY [t0].[CustomerID], [o].[OrderID]"); } public override async Task Multi_level_includes_are_applied_with_skip_take(bool async) @@ -1751,7 +1801,7 @@ public override async Task Multi_level_includes_are_applied_with_skip_take(bool AssertSql( @"@__p_0='1' -SELECT [t0].[CustomerID], [t1].[OrderID], [t1].[CustomerID], [t1].[EmployeeID], [t1].[OrderDate], [t1].[OrderID0], [t1].[ProductID], [t1].[Discount], [t1].[Quantity], [t1].[UnitPrice] +SELECT [t0].[CustomerID] FROM ( SELECT TOP(1) [t].[CustomerID] FROM ( @@ -1763,12 +1813,42 @@ OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY ) AS [t] ORDER BY [t].[CustomerID] ) AS [t0] -LEFT JOIN ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o0].[OrderID] AS [OrderID0], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice] - FROM [Orders] AS [o] - LEFT JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] -) AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID] -ORDER BY [t0].[CustomerID], [t1].[OrderID], [t1].[OrderID0], [t1].[ProductID]"); +ORDER BY [t0].[CustomerID]", + // + @"@__p_0='1' + +SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [t0].[CustomerID] +FROM ( + SELECT TOP(1) [t].[CustomerID] + FROM ( + SELECT [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY + ) AS [t] + ORDER BY [t].[CustomerID] +) AS [t0] +INNER JOIN [Orders] AS [o] ON [t0].[CustomerID] = [o].[CustomerID] +ORDER BY [t0].[CustomerID], [o].[OrderID]", + // + @"@__p_0='1' + +SELECT [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice], [t0].[CustomerID], [o].[OrderID] +FROM ( + SELECT TOP(1) [t].[CustomerID] + FROM ( + SELECT [c].[CustomerID] + FROM [Customers] AS [c] + WHERE [c].[CustomerID] LIKE N'A%' + ORDER BY [c].[CustomerID] + OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY + ) AS [t] + ORDER BY [t].[CustomerID] +) AS [t0] +INNER JOIN [Orders] AS [o] ON [t0].[CustomerID] = [o].[CustomerID] +INNER JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] +ORDER BY [t0].[CustomerID], [o].[OrderID]"); } public override async Task Filtered_include_with_multiple_ordering(bool async) @@ -1792,8 +1872,6 @@ FROM [Orders] AS [o] ORDER BY [o].[OrderID] OFFSET 1 ROWS ) AS [t] - ORDER BY [t].[OrderDate] DESC - OFFSET 0 ROWS ) AS [t0] WHERE [c].[CustomerID] LIKE N'F%' ORDER BY [c].[CustomerID], [t0].[OrderDate] DESC"); @@ -1822,7 +1900,33 @@ public override async Task Include_in_let_followed_by_FirstOrDefault(bool async) { await base.Include_in_let_followed_by_FirstOrDefault(async); - AssertSql(" "); + AssertSql( + @"SELECT [c].[CustomerID], [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate] +FROM [Customers] AS [c] +LEFT JOIN ( + SELECT [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate] + FROM ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], ROW_NUMBER() OVER(PARTITION BY [o].[CustomerID] ORDER BY [o].[OrderDate]) AS [row] + FROM [Orders] AS [o] + ) AS [t] + WHERE [t].[row] <= 1 +) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID] +WHERE [c].[CustomerID] LIKE N'F%' +ORDER BY [c].[CustomerID], [t0].[OrderID]", + // + @"SELECT [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice], [c].[CustomerID], [t0].[OrderID] +FROM [Customers] AS [c] +LEFT JOIN ( + SELECT [t].[OrderID], [t].[CustomerID] + FROM ( + SELECT [o].[OrderID], [o].[CustomerID], ROW_NUMBER() OVER(PARTITION BY [o].[CustomerID] ORDER BY [o].[OrderDate]) AS [row] + FROM [Orders] AS [o] + ) AS [t] + WHERE [t].[row] <= 1 +) AS [t0] ON [c].[CustomerID] = [t0].[CustomerID] +INNER JOIN [Order Details] AS [o0] ON [t0].[OrderID] = [o0].[OrderID] +WHERE [c].[CustomerID] LIKE N'F%' +ORDER BY [c].[CustomerID], [t0].[OrderID]"); } private void AssertSql(params string[] expected) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs index 1af9f88b1dc..0548b70a72d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs @@ -937,7 +937,7 @@ ORDER BY [t].[Id] FROM ( SELECT TOP(@__p_0) [t].[Id] FROM ( - SELECT DISTINCT [o].[Id], [o].[Discriminator], [o].[Name] + SELECT DISTINCT [o].[Id], [o].[Discriminator], [o].[Name], [o].[PersonAddress_AddressLine], [o].[PersonAddress_PlaceType], [o].[PersonAddress_ZipCode], [o].[PersonAddress_Country_Name], [o].[PersonAddress_Country_PlanetId], [o].[BranchAddress_BranchName], [o].[BranchAddress_PlaceType], [o].[BranchAddress_Country_Name], [o].[BranchAddress_Country_PlanetId], [o].[LeafBAddress_LeafBType], [o].[LeafBAddress_PlaceType], [o].[LeafBAddress_Country_Name], [o].[LeafBAddress_Country_PlanetId], [o].[LeafAAddress_LeafType], [o].[LeafAAddress_PlaceType], [o].[LeafAAddress_Country_Name], [o].[LeafAAddress_Country_PlanetId] FROM [OwnedPerson] AS [o] ) AS [t] ORDER BY [t].[Id] @@ -951,7 +951,7 @@ ORDER BY [t].[Id] FROM ( SELECT TOP(@__p_0) [t].[Id] FROM ( - SELECT DISTINCT [o].[Id], [o].[Discriminator], [o].[Name] + SELECT DISTINCT [o].[Id], [o].[Discriminator], [o].[Name], [o].[PersonAddress_AddressLine], [o].[PersonAddress_PlaceType], [o].[PersonAddress_ZipCode], [o].[PersonAddress_Country_Name], [o].[PersonAddress_Country_PlanetId], [o].[BranchAddress_BranchName], [o].[BranchAddress_PlaceType], [o].[BranchAddress_Country_Name], [o].[BranchAddress_Country_PlanetId], [o].[LeafBAddress_LeafBType], [o].[LeafBAddress_PlaceType], [o].[LeafBAddress_Country_Name], [o].[LeafBAddress_Country_PlanetId], [o].[LeafAAddress_LeafType], [o].[LeafAAddress_PlaceType], [o].[LeafAAddress_Country_Name], [o].[LeafAAddress_Country_PlanetId] FROM [OwnedPerson] AS [o] ) AS [t] ORDER BY [t].[Id] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs index 64cb05a93ae..59190009d79 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs @@ -8499,16 +8499,18 @@ FROM [Owner23211] AS [o] LEFT JOIN [Owned223211] AS [o1] ON [o].[Id] = [o1].[Owner23211Id] ORDER BY [o].[Id] ) AS [t] -ORDER BY [t].[Id]", +ORDER BY [t].[Id], [t].[Owner23211Id], [t].[Owner23211Id0]", // - @"SELECT [d].[Id], [d].[Owner23211Id], [t].[Id] + @"SELECT [d].[Id], [d].[Owner23211Id], [t].[Id], [t].[Owner23211Id], [t].[Owner23211Id0] FROM ( - SELECT TOP(1) [o].[Id] + SELECT TOP(1) [o].[Id], [o0].[Owner23211Id], [o1].[Owner23211Id] AS [Owner23211Id0] FROM [Owner23211] AS [o] + LEFT JOIN [Owned123211] AS [o0] ON [o].[Id] = [o0].[Owner23211Id] + LEFT JOIN [Owned223211] AS [o1] ON [o].[Id] = [o1].[Owner23211Id] ORDER BY [o].[Id] ) AS [t] INNER JOIN [Dependent23211] AS [d] ON [t].[Id] = [d].[Owner23211Id] -ORDER BY [t].[Id]"); +ORDER BY [t].[Id], [t].[Owner23211Id], [t].[Owner23211Id0]"); } using (var context = contextFactory.CreateContext()) @@ -8528,16 +8530,17 @@ FROM [SecondOwner23211] AS [s] LEFT JOIN [Owned23211] AS [o] ON [s].[Id] = [o].[SecondOwner23211Id] ORDER BY [s].[Id] ) AS [t] -ORDER BY [t].[Id]", +ORDER BY [t].[Id], [t].[SecondOwner23211Id]", // - @"SELECT [s0].[Id], [s0].[SecondOwner23211Id], [t].[Id] + @"SELECT [s0].[Id], [s0].[SecondOwner23211Id], [t].[Id], [t].[SecondOwner23211Id] FROM ( - SELECT TOP(1) [s].[Id] + SELECT TOP(1) [s].[Id], [o].[SecondOwner23211Id] FROM [SecondOwner23211] AS [s] + LEFT JOIN [Owned23211] AS [o] ON [s].[Id] = [o].[SecondOwner23211Id] ORDER BY [s].[Id] ) AS [t] INNER JOIN [SecondDependent23211] AS [s0] ON [t].[Id] = [s0].[SecondOwner23211Id] -ORDER BY [t].[Id]"); +ORDER BY [t].[Id], [t].[SecondOwner23211Id]"); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs index 04db0cf7354..c12b459070a 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs @@ -146,6 +146,20 @@ public virtual void Distinct_used_after_order_by() Fixture.TestSqlLoggerFactory.Log[1].Message); } + [ConditionalFact] + public virtual void Include_collection_does_not_generate_warning() + { + using var context = CreateContext(); + var customer = context.Set().Include(e => e.Orders).AsSplitQuery().Single(e => e.CustomerID == "ALFKI"); + + Assert.NotNull(customer); + Assert.Equal(6, customer.Orders.Count); + + Assert.DoesNotContain( + CoreResources.LogRowLimitingOperationWithoutOrderBy(new TestLogger()).GenerateMessage(), + Fixture.TestSqlLoggerFactory.Log.Select(e => e.Message)); + } + [ConditionalFact] public void SelectExpression_does_not_use_an_old_logger() { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs index 17865f22cdd..416774fd6fd 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs @@ -1034,7 +1034,7 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t0].[Id], [t0].[Name], [t0].[Number], [t0].[IsGreen], [t0].[Discriminator], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen], [t].[Discriminator] + SELECT [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen], [t].[Discriminator], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN ( SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE @@ -1061,7 +1061,7 @@ FROM [EntityTwos] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[TwoId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1081,7 +1081,7 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t0].[Id], [t0].[Name], [t0].[Number], [t0].[IsGreen], [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[LeafId] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen] + SELECT [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN ( SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen] @@ -1095,7 +1095,7 @@ FROM [Roots] AS [r] @"SELECT [t1].[Id], [t1].[Name], [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[LeafId], [t0].[Id] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [t].[Id] + SELECT [t].[Id], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN ( SELECT [r].[Id] @@ -1105,7 +1105,7 @@ FROM [Roots] AS [r] ) AS [t] ON [j].[LeafId] = [t].[Id] ) AS [t0] ON (([e].[Key1] = [t0].[CompositeId1]) AND ([e].[Key2] = [t0].[CompositeId2])) AND ([e].[Key3] = [t0].[CompositeId3]) INNER JOIN ( - SELECT [j0].[EntityBranchId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j0].[EntityBranchId] FROM [JoinOneToBranch] AS [j0] INNER JOIN [EntityOnes] AS [e0] ON [j0].[EntityOneId] = [e0].[Id] ) AS [t1] ON [t0].[Id] = [t1].[EntityBranchId] @@ -1124,7 +1124,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1134,13 +1134,13 @@ FROM [JoinOneToThreePayloadFull] AS [j] @"SELECT [t0].[Id], [t0].[Name], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id], [t].[Id0] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e1].[Id] AS [Id0] + SELECT [e0].[Id], [e1].[Id] AS [Id0], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [j0].[LeftId], [e2].[Id], [e2].[Name] + SELECT [e2].[Id], [e2].[Name], [j0].[LeftId] FROM [JoinOneSelfPayload] AS [j0] INNER JOIN [EntityOnes] AS [e2] ON [j0].[RightId] = [e2].[Id] ) AS [t0] ON [t].[Id] = [t0].[LeftId] @@ -1161,7 +1161,7 @@ FROM [EntityTwos] AS [e] FROM [EntityTwos] AS [e] LEFT JOIN [EntityThrees] AS [e0] ON [e].[Id] = [e0].[ReferenceInverseId] INNER JOIN ( - SELECT [e1].[EntityTwoId], [e2].[Id], [e2].[Name] + SELECT [e2].[Id], [e2].[Name], [e1].[EntityTwoId] FROM [EntityOneEntityTwo] AS [e1] INNER JOIN [EntityOnes] AS [e2] ON [e1].[EntityOneId] = [e2].[Id] ) AS [t] ON [e].[Id] = [t].[EntityTwoId] @@ -1180,7 +1180,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[ThreeId] FROM [JoinOneToThreePayloadFullShared] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1197,18 +1197,14 @@ public override async Task Filtered_include_skip_navigation_order_by_split(bool FROM [EntityThrees] AS [e] ORDER BY [e].[Id]", // - @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] + @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [t].[ThreeId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] - FROM ( - SELECT [j].[ThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[ThreeId] ORDER BY [e0].[Id]) AS [row] - FROM [JoinTwoToThree] AS [j] - INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [e].[Id] = [t0].[ThreeId] -ORDER BY [e].[Id], [t0].[ThreeId], [t0].[Id]"); + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[ThreeId] + FROM [JoinTwoToThree] AS [j] + INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_skip_split(bool async) @@ -1223,9 +1219,9 @@ FROM [EntityTwos] AS [e] @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [t].[LeftId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[LeftId] FROM ( - SELECT [j].[LeftId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[LeftId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[LeftId], ROW_NUMBER() OVER(PARTITION BY [j].[LeftId] ORDER BY [e0].[Id]) AS [row] FROM [JoinTwoSelfShared] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[RightId] = [e0].[Id] ) AS [t] @@ -1246,9 +1242,9 @@ FROM [EntityCompositeKeys] AS [e] @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3] FROM ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] FROM [JoinTwoToCompositeKeyShared] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] @@ -1266,18 +1262,18 @@ public override async Task Filtered_include_skip_navigation_order_by_skip_take_s FROM [EntityCompositeKeys] AS [e] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3]", // - @"SELECT [t0].[Id0], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] + @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Key1], [e].[Key2], [e].[Key3] FROM [EntityCompositeKeys] AS [e] INNER JOIN ( - SELECT [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[Id0], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3] FROM ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [e0].[Id] AS [Id0], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3] ORDER BY [e0].[Id]) AS [row] FROM [JoinThreeToCompositeKeyFull] AS [j] INNER JOIN [EntityThrees] AS [e0] ON [j].[ThreeId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON (([e].[Key1] = [t0].[CompositeId1]) AND ([e].[Key2] = [t0].[CompositeId2])) AND ([e].[Key3] = [t0].[CompositeId3]) -ORDER BY [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id0]"); +ORDER BY [e].[Key1], [e].[Key2], [e].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id]"); } public override async Task Filtered_then_include_skip_navigation_where_split(bool async) @@ -1297,7 +1293,7 @@ FROM [Roots] AS [r] @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [r].[Id], [t].[EntityRootId], [t].[EntityThreeId] FROM [Roots] AS [r] INNER JOIN ( - SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [e].[EntityRootId], [e].[EntityThreeId] FROM [EntityRootEntityThree] AS [e] INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] ) AS [t] ON [r].[Id] = [t].[EntityRootId] @@ -1306,12 +1302,12 @@ FROM [EntityRootEntityThree] AS [e] @"SELECT [t0].[Id], [t0].[Name], [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] FROM [Roots] AS [r] INNER JOIN ( - SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id] + SELECT [e0].[Id], [e].[EntityRootId], [e].[EntityThreeId] FROM [EntityRootEntityThree] AS [e] INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] ) AS [t] ON [r].[Id] = [t].[EntityRootId] INNER JOIN ( - SELECT [j].[ThreeId], [e1].[Id], [e1].[Name] + SELECT [e1].[Id], [e1].[Name], [j].[ThreeId] FROM [JoinOneToThreePayloadFullShared] AS [j] INNER JOIN [EntityOnes] AS [e1] ON [j].[OneId] = [e1].[Id] WHERE [e1].[Id] < 10 @@ -1336,29 +1332,29 @@ FROM [Roots] AS [r] @"SELECT [t].[Key1], [t].[Key2], [t].[Key3], [t].[Name], [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId] FROM [Roots] AS [r] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId], [e].[Key1], [e].[Key2], [e].[Key3], [e].[Name] + SELECT [e].[Key1], [e].[Key2], [e].[Key3], [e].[Name], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN [EntityCompositeKeys] AS [e] ON (([j].[CompositeId1] = [e].[Key1]) AND ([j].[CompositeId2] = [e].[Key2])) AND ([j].[CompositeId3] = [e].[Key3]) ) AS [t] ON [r].[Id] = [t].[RootId] ORDER BY [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3]", // - @"SELECT [t0].[Id0], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3] + @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3] FROM [Roots] AS [r] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId], [e].[Key1], [e].[Key2], [e].[Key3] + SELECT [e].[Key1], [e].[Key2], [e].[Key3], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[RootId] FROM [JoinCompositeKeyToRootShared] AS [j] INNER JOIN [EntityCompositeKeys] AS [e] ON (([j].[CompositeId1] = [e].[Key1]) AND ([j].[CompositeId2] = [e].[Key2])) AND ([j].[CompositeId3] = [e].[Key3]) ) AS [t] ON [r].[Id] = [t].[RootId] INNER JOIN ( - SELECT [t1].[CompositeId1], [t1].[CompositeId2], [t1].[CompositeId3], [t1].[Id0], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[CompositeId1], [t1].[CompositeId2], [t1].[CompositeId3] FROM ( - SELECT [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], [e0].[Id] AS [Id0], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], ROW_NUMBER() OVER(PARTITION BY [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] ORDER BY [e0].[Id]) AS [row] FROM [JoinThreeToCompositeKeyFull] AS [j0] INNER JOIN [EntityThrees] AS [e0] ON [j0].[ThreeId] = [e0].[Id] ) AS [t1] WHERE (1 < [t1].[row]) AND ([t1].[row] <= 3) ) AS [t0] ON (([t].[Key1] = [t0].[CompositeId1]) AND ([t].[Key2] = [t0].[CompositeId2])) AND ([t].[Key3] = [t0].[CompositeId3]) -ORDER BY [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id0]"); +ORDER BY [r].[Id], [t].[CompositeId1], [t].[CompositeId2], [t].[CompositeId3], [t].[RootId], [t].[Key1], [t].[Key2], [t].[Key3], [t0].[CompositeId1], [t0].[CompositeId2], [t0].[CompositeId3], [t0].[Id]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_split(bool async) @@ -1377,7 +1373,7 @@ FROM [Roots] AS [r] INNER JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] INNER JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [e].[Key1], [e].[Key2], [e].[Key3], [e].[Name] + SELECT [e].[Key1], [e].[Key2], [e].[Key3], [e].[Name], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN [EntityCompositeKeys] AS [e] ON (([j].[CompositeId1] = [e].[Key1]) AND ([j].[CompositeId2] = [e].[Key2])) AND ([j].[CompositeId3] = [e].[Key3]) WHERE [e].[Key1] < 5 @@ -1389,13 +1385,13 @@ FROM [Roots] AS [r] INNER JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] INNER JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] INNER JOIN ( - SELECT [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId], [e].[Key1], [e].[Key2], [e].[Key3] + SELECT [e].[Key1], [e].[Key2], [e].[Key3], [j].[CompositeId1], [j].[CompositeId2], [j].[CompositeId3], [j].[LeafId] FROM [JoinCompositeKeyToLeaf] AS [j] INNER JOIN [EntityCompositeKeys] AS [e] ON (([j].[CompositeId1] = [e].[Key1]) AND ([j].[CompositeId2] = [e].[Key2])) AND ([j].[CompositeId3] = [e].[Key3]) WHERE [e].[Key1] < 5 ) AS [t] ON [r].[Id] = [t].[LeafId] INNER JOIN ( - SELECT [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j0].[CompositeId1], [j0].[CompositeId2], [j0].[CompositeId3] FROM [JoinTwoToCompositeKeyShared] AS [j0] INNER JOIN [EntityTwos] AS [e0] ON [j0].[TwoId] = [e0].[Id] ) AS [t0] ON (([t].[Key1] = [t0].[CompositeId1]) AND ([t].[Key2] = [t0].[CompositeId2])) AND ([t].[Key3] = [t0].[CompositeId3]) @@ -1414,34 +1410,34 @@ FROM [EntityOnes] AS [e] @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [t].[OneId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] + SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [t].[OneId], [t].[TwoId] FROM ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[OneId], [j].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]", +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]", // @"SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [t].[OneId], [t].[TwoId], [t].[Id] + SELECT [t].[Id], [t].[OneId], [t].[TwoId] FROM ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] + SELECT [e0].[Id], [j].[OneId], [j].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j].[OneId] ORDER BY [e0].[Id]) AS [row] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] INNER JOIN ( - SELECT [j0].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[TwoId] FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 10 ) AS [t1] ON [t0].[Id] = [t1].[TwoId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]"); +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_order_by_skip_take_split(bool async) @@ -1456,7 +1452,7 @@ FROM [EntityOnes] AS [e] @"SELECT [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1466,15 +1462,15 @@ WHERE [e0].[Id] < 10 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId], [t].[Id] FROM [EntityOnes] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[OneId] INNER JOIN ( - SELECT [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[TwoId] FROM ( - SELECT [j0].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[TwoId] ORDER BY [e1].[Id]) AS [row] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[TwoId], ROW_NUMBER() OVER(PARTITION BY [j0].[TwoId] ORDER BY [e1].[Id]) AS [row] FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] ) AS [t1] @@ -1495,7 +1491,7 @@ FROM [EntityTwos] AS [e] @"SELECT [t].[Id], [t].[Name], [t].[Id0], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name0], [t].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId] + SELECT [e0].[Id], [e0].[Name], [e1].[Id] AS [Id0], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name] AS [Name0], [e1].[ReferenceInverseId], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1506,7 +1502,7 @@ WHERE [e0].[Id] < 10 @"SELECT [e2].[Id], [e2].[CollectionInverseId], [e2].[ExtraId], [e2].[Name], [e2].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[TwoId], [t].[Id], [t].[Id0] FROM [EntityTwos] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[TwoId], [e0].[Id], [e1].[Id] AS [Id0] + SELECT [e0].[Id], [e1].[Id] AS [Id0], [j].[OneId], [j].[TwoId] FROM [JoinOneToTwo] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] LEFT JOIN [EntityTwos] AS [e1] ON [e0].[Id] = [e1].[ReferenceInverseId] @@ -1528,7 +1524,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 @@ -1538,15 +1534,15 @@ WHERE [e0].[Id] < 10 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [t1].[OneId], [t1].[Id], [t1].[CollectionInverseId], [t1].[ExtraId], [t1].[Name], [t1].[ReferenceInverseId] + SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[ExtraId], [t1].[Name], [t1].[ReferenceInverseId], [t1].[OneId] FROM ( - SELECT [j0].[OneId], [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j0].[OneId] ORDER BY [e1].[Id]) AS [row] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[ExtraId], [e1].[Name], [e1].[ReferenceInverseId], [j0].[OneId], ROW_NUMBER() OVER(PARTITION BY [j0].[OneId] ORDER BY [e1].[Id]) AS [row] FROM [JoinOneToTwo] AS [j0] INNER JOIN [EntityTwos] AS [e1] ON [j0].[TwoId] = [e1].[Id] ) AS [t1] @@ -1557,13 +1553,13 @@ FROM [JoinOneToTwo] AS [j0] @"SELECT [t0].[Id], [t0].[Name], [t0].[Number], [t0].[IsGreen], [t0].[Discriminator], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] < 10 ) AS [t] ON [e].[Id] = [t].[ThreeId] INNER JOIN ( - SELECT [j0].[EntityOneId], [t1].[Id], [t1].[Name], [t1].[Number], [t1].[IsGreen], [t1].[Discriminator] + SELECT [t1].[Id], [t1].[Name], [t1].[Number], [t1].[IsGreen], [t1].[Discriminator], [j0].[EntityOneId] FROM [JoinOneToBranch] AS [j0] INNER JOIN ( SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE @@ -1590,7 +1586,7 @@ FROM [EntityThrees] AS [e] @"SELECT [t].[Id], [t].[Name], [e].[Id], [t].[OneId], [t].[ThreeId] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id], [e0].[Name] + SELECT [e0].[Id], [e0].[Name], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] > 15 @@ -1600,7 +1596,7 @@ WHERE [e0].[Id] > 15 @"SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [j].[OneId], [j].[ThreeId], [e0].[Id] + SELECT [e0].[Id], [j].[OneId], [j].[ThreeId] FROM [JoinOneToThreePayloadFull] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] WHERE [e0].[Id] > 15 @@ -1639,7 +1635,7 @@ FROM [EntityTwos] AS [e0] WHERE [e0].[Id] > 15 ) AS [t] ON [e].[Id] = [t].[CollectionInverseId] INNER JOIN ( - SELECT [j].[TwoId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + SELECT [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [j].[TwoId] FROM [JoinTwoToThree] AS [j] INNER JOIN [EntityThrees] AS [e1] ON [j].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 5 diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs index fd8eef85fb9..5db2ebe914f 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs @@ -1196,18 +1196,14 @@ public override async Task Filtered_include_skip_navigation_order_by_split(bool FROM [EntityThrees] AS [e] ORDER BY [e].[Id]", // - @"SELECT [t0].[ThreeId], [t0].[TwoId], [t0].[Id], [t0].[CollectionInverseId], [t0].[ExtraId], [t0].[Name], [t0].[ReferenceInverseId], [e].[Id] + @"SELECT [t].[ThreeId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] FROM [EntityThrees] AS [e] INNER JOIN ( - SELECT [t].[ThreeId], [t].[TwoId], [t].[Id], [t].[CollectionInverseId], [t].[ExtraId], [t].[Name], [t].[ReferenceInverseId] - FROM ( - SELECT [j].[ThreeId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId], ROW_NUMBER() OVER(PARTITION BY [j].[ThreeId] ORDER BY [e0].[Id]) AS [row] - FROM [JoinTwoToThree] AS [j] - INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] - ) AS [t] - WHERE 0 < [t].[row] -) AS [t0] ON [e].[Id] = [t0].[ThreeId] -ORDER BY [e].[Id], [t0].[ThreeId], [t0].[Id]"); + SELECT [j].[ThreeId], [j].[TwoId], [e0].[Id], [e0].[CollectionInverseId], [e0].[ExtraId], [e0].[Name], [e0].[ReferenceInverseId] + FROM [JoinTwoToThree] AS [j] + INNER JOIN [EntityTwos] AS [e0] ON [j].[TwoId] = [e0].[Id] +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_skip_split(bool async) @@ -1421,7 +1417,7 @@ FROM [JoinOneToTwo] AS [j] ) AS [t] WHERE (1 < [t].[row]) AND ([t].[row] <= 3) ) AS [t0] ON [e].[Id] = [t0].[OneId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]", +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]", // @"SELECT [t1].[ThreeId], [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id] FROM [EntityOnes] AS [e] @@ -1440,7 +1436,7 @@ FROM [JoinTwoToThree] AS [j0] INNER JOIN [EntityThrees] AS [e1] ON [j0].[ThreeId] = [e1].[Id] WHERE [e1].[Id] < 10 ) AS [t1] ON [t0].[Id] = [t1].[TwoId] -ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]"); +ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]"); } public override async Task Filtered_include_skip_navigation_where_then_include_skip_navigation_order_by_skip_take_split(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqliteTest.cs index 54c62980632..1308b04bc48 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqliteTest.cs @@ -15,11 +15,11 @@ public ComplexNavigationsCollectionsQuerySqliteTest(ComplexNavigationsQuerySqlit { } - [ConditionalTheory(Skip = "Issue #17230")] - public override Task Include_inside_subquery(bool async) - { - return base.Include_inside_subquery(async); - } + public override async Task Include_inside_subquery(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Include_inside_subquery(async))).Message); public override async Task Filtered_include_after_different_filtered_include_different_level(bool async) => Assert.Equal( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqliteTest.cs index 12788a18c38..90d19f129eb 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQuerySqliteTest.cs @@ -15,13 +15,26 @@ public ComplexNavigationsCollectionsSplitQuerySqliteTest(ComplexNavigationsQuery { } + public override async Task Include_inside_subquery(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Include_inside_subquery(async))).Message); + + public override async Task Filtered_include_outer_parameter_used_inside_filter(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Filtered_include_outer_parameter_used_inside_filter(async))).Message); + public override async Task Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(async))).Message); - public override async Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only(bool async) + public override async Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only( + bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( @@ -32,5 +45,23 @@ public override async Task Filtered_include_same_filter_set_on_same_navigation_t SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Filtered_include_same_filter_set_on_same_navigation_twice_followed_by_ThenIncludes(async))).Message); + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault(async))).Message); + + public override async Task Take_Select_collection_Take(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Take_Select_collection_Take(async))).Message); + + public override async Task Skip_Take_Select_collection_Skip_Take(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Skip_Take_Select_collection_Skip_Take(async))).Message); } } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQuerySqliteTest.cs index 590fde73690..8cb2454dd81 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQuerySqliteTest.cs @@ -17,13 +17,20 @@ public ComplexNavigationsCollectionsSplitSharedTypeQuerySqliteTest(ComplexNaviga { } + public override async Task Filtered_include_outer_parameter_used_inside_filter(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Filtered_include_outer_parameter_used_inside_filter(async))).Message); + public override async Task Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Filtered_include_and_non_filtered_include_followed_by_then_include_on_same_navigation(async))).Message); - public override async Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only(bool async) + public override async Task Filtered_include_multiple_multi_level_includes_with_first_level_using_filter_include_on_one_of_the_chains_only( + bool async) => Assert.Equal( SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( @@ -34,5 +41,23 @@ public override async Task Filtered_include_same_filter_set_on_same_navigation_t SqliteStrings.ApplyNotSupported, (await Assert.ThrowsAsync( () => base.Filtered_include_same_filter_set_on_same_navigation_twice_followed_by_ThenIncludes(async))).Message); + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault(async))).Message); + + public override async Task Take_Select_collection_Take(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Take_Select_collection_Take(async))).Message); + + public override async Task Skip_Take_Select_collection_Skip_Take(bool async) + => Assert.Equal( + SqliteStrings.ApplyNotSupported, + (await Assert.ThrowsAsync( + () => base.Skip_Take_Select_collection_Skip_Take(async))).Message); } }