From b0607d0a4ae5401e3d870f19166c68ebd0db0fbc Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 11 Jan 2024 16:59:44 +0100 Subject: [PATCH] Redo query column/table relationship without TableReferenceExpression Closes #32558 --- EFCore.sln.DotSettings | 2 + .../Internal/TableReferenceExpression.cs | 126 -- ...nslatingExpressionVisitor.ExecuteUpdate.cs | 33 +- ...yableMethodTranslatingExpressionVisitor.cs | 125 +- .../Query/SqlAliasManager.cs | 34 +- .../Query/SqlExpressions/ColumnExpression.cs | 62 +- .../SqlExpressions/JoinExpressionBase.cs | 9 + .../SqlExpressions/SelectExpression.Helper.cs | 399 +---- .../Query/SqlExpressions/SelectExpression.cs | 662 ++++----- .../SqlExpressions/TableExpressionBase.cs | 10 + .../Query/SqlNullabilityProcessor.cs | 2 +- src/EFCore.Relational/Query/SqlTreePruner.cs | 47 +- .../StructuralTypeProjectionExpression.cs | 18 +- .../Internal/SqlServerJsonPostprocessor.cs | 72 +- .../SqlServerQueryTranslationPostprocessor.cs | 8 +- ...yableMethodTranslatingExpressionVisitor.cs | 24 +- .../Query/Internal/SqlServerSqlTreePruner.cs | 2 +- ...yableMethodTranslatingExpressionVisitor.cs | 39 +- .../ComplexTypeBulkUpdatesSqlServerTest.cs | 24 +- .../EntitySplittingQuerySqlServerTest.cs | 12 +- ...orthwindMiscellaneousQuerySqlServerTest.cs | 20 +- .../Query/TPCGearsOfWarQuerySqlServerTest.cs | 312 ++-- ...CManyToManyNoTrackingQuerySqlServerTest.cs | 106 +- .../Query/TPCManyToManyQuerySqlServerTest.cs | 106 +- .../TPCRelationshipsQuerySqlServerTest.cs | 1312 ++++++++--------- .../NorthwindBulkUpdatesSqliteTest.cs | 10 +- .../Query/JsonQuerySqliteTest.cs | 4 +- 27 files changed, 1518 insertions(+), 2062 deletions(-) delete mode 100644 src/EFCore.Relational/Query/Internal/TableReferenceExpression.cs diff --git a/EFCore.sln.DotSettings b/EFCore.sln.DotSettings index 6e44bcd4b12..db9af702c23 100644 --- a/EFCore.sln.DotSettings +++ b/EFCore.sln.DotSettings @@ -288,6 +288,7 @@ The .NET Foundation licenses this file to you under the MIT license. True True True + True True True True @@ -326,6 +327,7 @@ The .NET Foundation licenses this file to you under the MIT license. True True True + True True True diff --git a/src/EFCore.Relational/Query/Internal/TableReferenceExpression.cs b/src/EFCore.Relational/Query/Internal/TableReferenceExpression.cs deleted file mode 100644 index 0d65030c00d..00000000000 --- a/src/EFCore.Relational/Query/Internal/TableReferenceExpression.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.Query.SqlExpressions; - -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 sealed class TableReferenceExpression : Expression -{ - private SelectExpression _selectExpression; - - /// - /// 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 TableReferenceExpression(SelectExpression selectExpression, string alias) - { - _selectExpression = selectExpression; - Alias = alias; - } - - /// - /// 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 TableExpressionBase Table - { - get - { - var table = _selectExpression.Tables.SingleOrDefault( - e => string.Equals((e as JoinExpressionBase)?.Table.Alias ?? e.Alias, Alias, StringComparison.OrdinalIgnoreCase)); - Check.DebugAssert( - table is not null, - $"Mismatched {nameof(TableReferenceExpression)}: couldn't find table alias '{Alias}' in referenced select expression's tables: " - + Environment.NewLine - + Environment.NewLine - + ExpressionPrinter.Print(_selectExpression)); - return table; - } - } - - /// - /// 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 string Alias { get; internal set; } - - /// - /// 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 override Type Type - => typeof(object); - - /// - /// 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 override ExpressionType NodeType - => ExpressionType.Extension; - - /// - /// 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. - /// - protected override Expression VisitChildren(ExpressionVisitor visitor) - => this; - - /// - /// 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 void UpdateTableReference(SelectExpression oldSelect, SelectExpression newSelect) - { - if (ReferenceEquals(oldSelect, _selectExpression)) - { - _selectExpression = newSelect; - } - } - - internal void Verify(SelectExpression selectExpression) - { - if (!ReferenceEquals(selectExpression, _selectExpression)) - { - throw new InvalidOperationException("Dangling TableReferenceExpression."); - } - } - - /// - public override bool Equals(object? obj) - => obj != null - && (ReferenceEquals(this, obj) - || obj is TableReferenceExpression tableReferenceExpression - && Equals(tableReferenceExpression)); - - // Since table reference is owned by SelectExpression, the select expression should be the same reference if they are matching. - // That means we also don't need to compute the hashcode for it. - // This allows us to break the cycle in computation when traversing this graph. - private bool Equals(TableReferenceExpression tableReferenceExpression) - => string.Equals(Alias, tableReferenceExpression.Alias, StringComparison.OrdinalIgnoreCase) - && ReferenceEquals(_selectExpression, tableReferenceExpression._selectExpression); - - /// - public override int GetHashCode() - => 0; -} diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs index 3569fb762eb..3ce347de25b 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs @@ -51,6 +51,8 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor return null; } + var selectExpression = (SelectExpression)source.QueryExpression; + // Translate the setters: the left (property) selectors get translated to ColumnExpressions, the right (value) selectors to // arbitrary SqlExpressions. // Note that if the query isn't natively supported, we'll do a pushdown (see PushdownWithPkInnerJoinPredicate below); if that @@ -61,10 +63,17 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor return null; } + if (targetTable is TpcTablesExpression tpcTablesExpression) + { + AddTranslationErrorDetails( + RelationalStrings.ExecuteOperationOnTPC( + nameof(RelationalQueryableExtensions.ExecuteUpdate), tpcTablesExpression.EntityType.DisplayName())); + return null; + } + // Check if the provider has a native translation for the update represented by the select expression. // The default relational implementation handles simple, universally-supported cases (i.e. no operators except for predicate). // Providers may override IsValidSelectExpressionForExecuteUpdate to add support for more cases via provider-specific UPDATE syntax. - var selectExpression = (SelectExpression)source.QueryExpression; if (IsValidSelectExpressionForExecuteUpdate(selectExpression, targetTable, out var tableExpression)) { selectExpression.ReplaceProjection(new List()); @@ -114,10 +123,8 @@ bool TranslateSetters( [NotNullWhen(true)] out List? translatedSetters, [NotNullWhen(true)] out TableExpressionBase? targetTable) { - var selectExpression = (SelectExpression)source.QueryExpression; - targetTable = null; - TableExpressionBase? tempTargetTable = null; + string? targetTableAlias = null; var tempTranslatedSetters = new List(); translatedSetters = null; @@ -165,29 +172,21 @@ bool TranslateSetters( } } - targetTable = tempTargetTable; translatedSetters = tempTranslatedSetters; - Check.DebugAssert(targetTable is not null, "Target table should have a value"); - - if (targetTable is TpcTablesExpression tpcTablesExpression) - { - AddTranslationErrorDetails( - RelationalStrings.ExecuteOperationOnTPC( - nameof(RelationalQueryableExtensions.ExecuteUpdate), tpcTablesExpression.EntityType.DisplayName())); - return false; - } + Check.DebugAssert(targetTableAlias is not null, "Target table alias should have a value"); + targetTable = selectExpression.Tables.First(t => t.GetRequiredAlias() == targetTableAlias); return true; bool IsColumnOnSameTable(ColumnExpression column, LambdaExpression propertySelector) { - if (tempTargetTable is null) + if (targetTableAlias is null) { - tempTargetTable = column.Table; + targetTableAlias = column.TableAlias; targetTablePropertySelector = propertySelector; } - else if (!ReferenceEquals(column.Table, tempTargetTable)) + else if (!ReferenceEquals(column.TableAlias, targetTableAlias)) { AddTranslationErrorDetails( RelationalStrings.MultipleTablesInExecuteUpdate( diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs index 7ab68fa9893..3cc2cf5ed83 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -1322,7 +1322,7 @@ protected override ShapedQueryExpression TranslateUnion(ShapedQueryExpression so /// protected virtual Expression ApplyInferredTypeMappings( Expression expression, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) => new RelationalInferredTypeMappingApplier( RelationalDependencies.Model, _sqlExpressionFactory, inferredTypeMappings).Visit(expression); @@ -1652,7 +1652,7 @@ Expression ExpandOwnedNavigation(INavigation navigation) ? foreignKey.Properties[0] : foreignKey.PrincipalKey.Properties[0]); - var sourceTable = FindRootTableExpressionForColumn(sourceColumn); + var sourceTable = FindRootTableExpressionForColumn(_selectExpression, sourceColumn); var innerSelectExpression = sqlExpressionFactory.Select(targetEntityType, _sqlAliasManager); innerSelectExpression = (SelectExpression)new AnnotationApplyingExpressionVisitor(sourceTable.GetAnnotations().ToList()) .Visit(innerSelectExpression); @@ -1709,23 +1709,20 @@ outerKey is NewArrayExpression newArrayExpression entityProjectionExpression, navigation, sqlExpressionFactory, _sqlAliasManager); } - static TableExpressionBase FindRootTableExpressionForColumn(ColumnExpression column) + static TableExpressionBase FindRootTableExpressionForColumn(SelectExpression select, ColumnExpression column) { - var table = column.Table; - if (table is JoinExpressionBase joinExpressionBase) - { - table = joinExpressionBase.Table; - } - else if (table is SetOperationBase setOperationBase) + var table = select.GetTable(column).UnwrapJoin(); + + if (table is SetOperationBase setOperationBase) { table = setOperationBase.Source1; } - if (table is SelectExpression selectExpression) + if (table is SelectExpression innerSelect) { - var matchingProjection = (ColumnExpression)selectExpression.Projection.Single(p => p.Alias == column.Name).Expression; + var matchingProjection = (ColumnExpression)innerSelect.Projection.Single(p => p.Alias == column.Name).Expression; - return FindRootTableExpressionForColumn(matchingProjection); + return FindRootTableExpressionForColumn(innerSelect, matchingProjection); } return table; @@ -2081,8 +2078,8 @@ private bool TryExtractBareInlineCollectionValues(ShapedQueryExpression shapedQu // Note that we assume ordering doesn't matter (Contains/Min/Max) } // Make sure that the source projects the column from the ValuesExpression directly, i.e. no projection out with some expression - && projection is ColumnExpression projectedColumn - && projectedColumn.Table == valuesExpression) + && projection is ColumnExpression { TableAlias: var tableAlias } + && tableAlias == valuesExpression.Alias) { values = new SqlExpression[valuesExpression.RowValues.Count]; @@ -2123,14 +2120,22 @@ private bool TryExtractBareInlineCollectionValues(ShapedQueryExpression shapedQu /// private sealed class ColumnTypeMappingScanner : ExpressionVisitor { - private readonly Dictionary<(TableExpressionBase, string), RelationalTypeMapping?> _inferredColumns = new(); + private readonly Dictionary<(string TableAlias, string ColumnName), RelationalTypeMapping?> _inferredColumns = new(); - private SelectExpression? _currentSelectExpression; + /// + /// A mapping of table aliases to the instances; these are used to check the table type + /// when we encounter a typed column pointing to it, and avoid recording inferred type mappings where we know the table + /// doesn't need to be inferred from the column. + /// + private readonly Dictionary _tables = new(); + + private string? _currentSelectTableAlias; private ProjectionExpression? _currentProjectionExpression; - public IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> Scan(Expression expression) + public IReadOnlyDictionary<(string, string), RelationalTypeMapping?> Scan(Expression expression) { _inferredColumns.Clear(); + _tables.Clear(); Visit(expression); @@ -2139,6 +2144,11 @@ private sealed class ColumnTypeMappingScanner : ExpressionVisitor protected override Expression VisitExtension(Expression node) { + if (node is TableExpressionBase { Alias: string tableAlias } table) + { + _tables[tableAlias] = table.UnwrapJoin(); + } + switch (node) { // A column on a table which was possibly originally untyped (constant/parameter root or a subquery projection of one), @@ -2157,12 +2167,16 @@ protected override Expression VisitExtension(Expression node) { TypeMapping: { } typeMapping, Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] - } - when WasMaybeOriginallyUntyped(columnExpression): + }: { - RegisterInferredTypeMapping(columnExpression, typeMapping); + var visitedSubquery = base.VisitExtension(node); - return base.VisitExtension(node); + if (WasMaybeOriginallyUntyped(columnExpression)) + { + RegisterInferredTypeMapping(columnExpression, typeMapping); + } + + return visitedSubquery; } // InExpression over a subquery: apply the item's type mapping on the subquery @@ -2170,12 +2184,16 @@ when WasMaybeOriginallyUntyped(columnExpression): { Item.TypeMapping: { } typeMapping, Subquery.Projection: [{ Expression: ColumnExpression columnExpression }] - } - when WasMaybeOriginallyUntyped(columnExpression): + }: { - RegisterInferredTypeMapping(columnExpression, typeMapping); + var visited = base.VisitExtension(node); - return base.VisitExtension(node); + if (WasMaybeOriginallyUntyped(columnExpression)) + { + RegisterInferredTypeMapping(columnExpression, typeMapping); + } + + return visited; } // For set operations involving a leg with a type mapping (e.g. some column) and a leg without one (queryable constant or @@ -2187,12 +2205,19 @@ when WasMaybeOriginallyUntyped(columnExpression): } when UnwrapConvert(projection1) is ColumnExpression column1 && UnwrapConvert(projection2) is ColumnExpression column2: { - if (projection1.TypeMapping is not null && WasMaybeOriginallyUntyped(column2)) + // Note that we can't use WasMaybeOriginallyUntyped() here like in the other cases, since that only works after we've + // visited the table the column points to (and populated the mapping in _tables). But with set operations specifically, + // we must call RegisterInferredTypeMapping *before* visiting, to infer from one side to the other so that that + // inference can propagate to subqueries nested within the set operation (chicken and egg problem). + // This only results in RegisterInferredTypeMapping being called when it doesn't have it (i.e. _inferredColumns + // contains more than it has to). + + if (projection1.TypeMapping is not null) { RegisterInferredTypeMapping(column2, projection1.TypeMapping); } - if (projection2.TypeMapping is not null && WasMaybeOriginallyUntyped(column1)) + if (projection2.TypeMapping is not null) { RegisterInferredTypeMapping(column1, projection2.TypeMapping); } @@ -2204,10 +2229,10 @@ when UnwrapConvert(projection1) is ColumnExpression column1 && UnwrapConvert(pro // projections they're in (see below). case SelectExpression selectExpression: { - var parentSelectExpression = _currentSelectExpression; - _currentSelectExpression = selectExpression; + var parentSelectTableAlias = _currentSelectTableAlias; + _currentSelectTableAlias = selectExpression.Alias; var visited = base.VisitExtension(selectExpression); - _currentSelectExpression = parentSelectExpression; + _currentSelectTableAlias = parentSelectTableAlias; return visited; } @@ -2224,10 +2249,10 @@ when UnwrapConvert(projection1) is ColumnExpression column1 && UnwrapConvert(pro // So we record state above to know which subquery and projection we're visiting; when visiting columns inside a projection // which has an inferred type mapping from above, we register the inferred type mapping for that column too. case ColumnExpression { TypeMapping: null } columnExpression - when _currentSelectExpression is not null + when _currentSelectTableAlias is not null && _currentProjectionExpression is not null && _inferredColumns.TryGetValue( - (_currentSelectExpression, _currentProjectionExpression.Alias), out var inferredTypeMapping) + (_currentSelectTableAlias, _currentProjectionExpression.Alias), out var inferredTypeMapping) && inferredTypeMapping is not null && WasMaybeOriginallyUntyped(columnExpression): { @@ -2242,13 +2267,12 @@ when _currentSelectExpression is not null return base.VisitExtension(node); } - static bool WasMaybeOriginallyUntyped(ColumnExpression columnExpression) + bool WasMaybeOriginallyUntyped(ColumnExpression columnExpression) { - var underlyingTable = columnExpression.Table is JoinExpressionBase joinExpression - ? joinExpression.Table - : columnExpression.Table; + var found = _tables.TryGetValue(columnExpression.TableAlias, out var table); + Check.DebugAssert(found, $"Column '{columnExpression}' points to a table that isn't in scope"); - return underlyingTable switch + return table switch { // TableExpressions are always fully-typed, with type mappings coming from the model TableExpression @@ -2279,11 +2303,9 @@ SqlExpression UnwrapConvert(SqlExpression expression) private void RegisterInferredTypeMapping(ColumnExpression columnExpression, RelationalTypeMapping inferredTypeMapping) { - var underlyingTable = columnExpression.Table is JoinExpressionBase joinExpression - ? joinExpression.Table - : columnExpression.Table; + var tableAlias = columnExpression.TableAlias; - if (_inferredColumns.TryGetValue((underlyingTable, columnExpression.Name), out var knownTypeMapping) + if (_inferredColumns.TryGetValue((tableAlias, columnExpression.Name), out var knownTypeMapping) && knownTypeMapping is not null && inferredTypeMapping.StoreType != knownTypeMapping.StoreType) { @@ -2291,11 +2313,11 @@ private void RegisterInferredTypeMapping(ColumnExpression columnExpression, Rela // Null out the value for the inferred type mapping as an indication of the conflict. If it turns out that we need the // inferred mapping later, during the application phase, we'll throw an exception at that point (not all the inferred type // mappings here will actually be needed, so we don't want to needlessly throw here). - _inferredColumns[(underlyingTable, columnExpression.Name)] = null; + _inferredColumns[(tableAlias, columnExpression.Name)] = null; return; } - _inferredColumns[(underlyingTable, columnExpression.Name)] = inferredTypeMapping; + _inferredColumns[(tableAlias, columnExpression.Name)] = inferredTypeMapping; } } @@ -2311,7 +2333,7 @@ protected class RelationalInferredTypeMappingApplier : ExpressionVisitor /// /// The inferred type mappings to be applied back on their query roots. /// - private readonly IReadOnlyDictionary<(TableExpressionBase Table, string ColumnName), RelationalTypeMapping?> _inferredTypeMappings; + private readonly IReadOnlyDictionary<(string TableAlias, string ColumnName), RelationalTypeMapping?> _inferredTypeMappings; /// /// Creates a new instance of the class. @@ -2322,7 +2344,7 @@ protected class RelationalInferredTypeMappingApplier : ExpressionVisitor public RelationalInferredTypeMappingApplier( IModel model, ISqlExpressionFactory sqlExpressionFactory, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) { Model = model; _sqlExpressionFactory = sqlExpressionFactory; @@ -2337,16 +2359,16 @@ public RelationalInferredTypeMappingApplier( /// /// Attempts to find an inferred type mapping for the given table column. /// - /// The table containing the column for which to find the inferred type mapping. + /// The alias of the table containing the column for which to find the inferred type mapping. /// The name of the column for which to find the inferred type mapping. /// The inferred type mapping, or if none could be found. /// Whether an inferred type mapping could be found. protected virtual bool TryGetInferredTypeMapping( - TableExpressionBase table, + string tableAlias, string columnName, [NotNullWhen(true)] out RelationalTypeMapping? inferredTypeMapping) { - if (_inferredTypeMappings.TryGetValue((table, columnName), out inferredTypeMapping)) + if (_inferredTypeMappings.TryGetValue((tableAlias, columnName), out inferredTypeMapping)) { // The inferred type mapping scanner records a null when two conflicting type mappings were inferred for the same // column. @@ -2369,7 +2391,7 @@ protected override Expression VisitExtension(Expression expression) switch (expression) { case ColumnExpression { TypeMapping: null } columnExpression - when TryGetInferredTypeMapping(columnExpression.Table, columnExpression.Name, out var typeMapping): + when TryGetInferredTypeMapping(columnExpression.TableAlias, columnExpression.Name, out var typeMapping): return columnExpression.ApplyTypeMapping(typeMapping); case SelectExpression selectExpression: @@ -2388,7 +2410,8 @@ when TryGetInferredTypeMapping(columnExpression.Table, columnExpression.Name, ou valuesExpression, stripOrdering: _currentSelectExpression is { Limit: null, Offset: null } && !_currentSelectExpression.Projection.Any( - p => p.Expression is ColumnExpression { Name: ValuesOrderingColumnName } c && c.Table == valuesExpression)); + p => p.Expression is ColumnExpression { Name: ValuesOrderingColumnName } c + && c.TableAlias == valuesExpression.Alias)); // SqlExpressions without an inferred type mapping indicates a problem in EF - everything should have been inferred. // One exception is SqlFragmentExpression, which never has a type mapping. @@ -2411,7 +2434,7 @@ when TryGetInferredTypeMapping(columnExpression.Table, columnExpression.Name, ou /// Whether to strip the _ord column. protected virtual ValuesExpression ApplyTypeMappingsOnValuesExpression(ValuesExpression valuesExpression, bool stripOrdering) { - var inferredTypeMappings = TryGetInferredTypeMapping(valuesExpression, ValuesValueColumnName, out var typeMapping) + var inferredTypeMappings = TryGetInferredTypeMapping(valuesExpression.Alias, ValuesValueColumnName, out var typeMapping) ? [null, typeMapping] : new RelationalTypeMapping?[] { null, null }; diff --git a/src/EFCore.Relational/Query/SqlAliasManager.cs b/src/EFCore.Relational/Query/SqlAliasManager.cs index 14995a3ce8e..d3ed60f43a2 100644 --- a/src/EFCore.Relational/Query/SqlAliasManager.cs +++ b/src/EFCore.Relational/Query/SqlAliasManager.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; -using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; namespace Microsoft.EntityFrameworkCore.Query; @@ -169,7 +168,7 @@ protected override Expression VisitExtension(Expression node) private sealed class TableAliasRewriter(IReadOnlyDictionary aliasRewritingMap) : ExpressionVisitor { - private readonly HashSet _visitedTableReferences = new(ReferenceEqualityComparer.Instance); + private readonly HashSet _visitedTables = new(ReferenceEqualityComparer.Instance); internal static Expression Rewrite(Expression expression, IReadOnlyDictionary aliasRewritingMap) => new TableAliasRewriter(aliasRewritingMap).Visit(expression); @@ -181,21 +180,28 @@ protected override Expression VisitExtension(Expression node) case ShapedQueryExpression shapedQuery: return shapedQuery.UpdateQueryExpression(Visit(shapedQuery.QueryExpression)); - case SelectExpression select: - for (var i = 0; i < select.Tables.Count; i++) + // Note that this skips joins (which wrap the table that has the actual alias), as well as the top-level select + case TableExpressionBase { Alias: string alias } table: + // TODO: Needed only because TableExpressionBase is still mutable with regards to its alias - remove after that's gone. + if (!_visitedTables.Add(table)) { - var table = select.Tables[i]; - - if (aliasRewritingMap.TryGetValue(table.UnwrapJoin().Alias!, out var newAlias)) - { - // TableReferenceExpression instances can (currently) be shared by multiple SelectExpression instances in the - // same tree. We don't want to the same one multiple times, so we track the ones we already visited. - // This will all go away soon as we get rid of TableReferenceExpression altogether. - select.ChangeTableAlias(i, newAlias, _visitedTableReferences); - } + return table; } - return base.VisitExtension(node); + if (aliasRewritingMap.TryGetValue(alias, out var newAlias)) + { + // TODO: TableExpressionBase is still mutable with regards to its alias - this needs to change. + // TODO: This visitor needs to replace the table in the usual way; but we don't currently have a good way of + // TODO: recreating a new TableExpressionBase implementation with a different alias. + // TODO: Either add a mandatory, abstract non-destructive ChangeAlias to TableExpressionBase, or ideally, + // TODO: refactor things to split the alias out of TableExpressionBase altogether. + table.Alias = newAlias; + } + + return base.VisitExtension(table); + + case ColumnExpression column when aliasRewritingMap.TryGetValue(column.TableAlias, out var newTableAlias): + return new ColumnExpression(column.Name, newTableAlias, column.Type, column.TypeMapping, column.IsNullable); default: return base.VisitExtension(node); diff --git a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs index 79971bd9325..06a79f6697a 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/ColumnExpression.cs @@ -13,55 +13,85 @@ namespace Microsoft.EntityFrameworkCore.Query.SqlExpressions; /// /// [DebuggerDisplay("{TableAlias}.{Name}")] -public abstract class ColumnExpression : SqlExpression +public class ColumnExpression : SqlExpression { /// /// Creates a new instance of the class. /// + /// The name of the column. + /// The alias of the table to which this column refers. /// The of the expression. /// The associated with the expression. - protected ColumnExpression(Type type, RelationalTypeMapping? typeMapping) + /// Whether this expression represents a nullable column. + public ColumnExpression( + string name, + string tableAlias, + Type type, + RelationalTypeMapping? typeMapping, + bool nullable) : base(type, typeMapping) { + Name = name; + TableAlias = tableAlias; + IsNullable = nullable; } /// /// The name of the column. /// - public abstract string Name { get; } - - /// - /// The table from which column is being referenced. - /// - public abstract TableExpressionBase Table { get; } + public virtual string Name { get; } /// /// The alias of the table from which column is being referenced. /// - public abstract string TableAlias { get; } + public virtual string TableAlias { get; } /// /// The bool value indicating if this column can have null values. /// - public abstract bool IsNullable { get; } + public virtual bool IsNullable { get; } + + /// + protected override Expression VisitChildren(ExpressionVisitor visitor) + => this; /// /// Makes this column nullable. /// /// A new expression which has property set to true. - public abstract ColumnExpression MakeNullable(); + public virtual ColumnExpression MakeNullable() + => IsNullable ? this : new ColumnExpression(Name, TableAlias, Type, TypeMapping, true); /// /// Applies supplied type mapping to this expression. /// /// A relational type mapping to apply. /// A new expression which has supplied type mapping. - public abstract SqlExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping); + public virtual SqlExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping) + => new ColumnExpression(Name, TableAlias, Type, typeMapping, IsNullable); /// protected override void Print(ExpressionPrinter expressionPrinter) - { - expressionPrinter.Append(TableAlias).Append("."); - expressionPrinter.Append(Name); - } + => expressionPrinter.Append(TableAlias).Append(".").Append(Name); + + /// + public override string ToString() + => $"{TableAlias}.{Name}"; + + /// + public override bool Equals(object? obj) + => obj != null + && (ReferenceEquals(this, obj) + || obj is ColumnExpression columnExpression + && Equals(columnExpression)); + + private bool Equals(ColumnExpression columnExpression) + => base.Equals(columnExpression) + && Name == columnExpression.Name + && TableAlias == columnExpression.TableAlias + && IsNullable == columnExpression.IsNullable; + + /// + public override int GetHashCode() + => HashCode.Combine(base.GetHashCode(), Name, TableAlias, IsNullable); } diff --git a/src/EFCore.Relational/Query/SqlExpressions/JoinExpressionBase.cs b/src/EFCore.Relational/Query/SqlExpressions/JoinExpressionBase.cs index e73625de178..96658271fa7 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/JoinExpressionBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/JoinExpressionBase.cs @@ -52,6 +52,15 @@ protected JoinExpressionBase(TableExpressionBase table, bool prunable, IEnumerab public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloningExpressionVisitor) => (TableExpressionBase)VisitChildren(cloningExpressionVisitor); + /// + /// 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 override string GetRequiredAlias() + => Table.GetRequiredAlias(); + /// public override bool Equals(object? obj) => obj != null diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs index c18f7fd525b..d4fd9932b6c 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs @@ -44,7 +44,7 @@ public bool ContainsOuterReference(SelectExpression selectExpression) } if (expression is ColumnExpression columnExpression - && _outerSelectExpression.ContainsTableReference(columnExpression)) + && _outerSelectExpression.ContainsReferencedTable(columnExpression)) { _containsOuterReference = true; @@ -155,25 +155,17 @@ public ProjectionIndexRemappingExpressionVisitor( } } - private sealed class SqlRemappingVisitor : ExpressionVisitor + private sealed class SqlRemappingVisitor( + Dictionary mappings, + SelectExpression subquery, + string tableAlias) + : ExpressionVisitor { - private readonly SelectExpression _subquery; - private readonly TableReferenceExpression _tableReferenceExpression; - private readonly Dictionary _mappings; - private readonly HashSet _correlatedTerms; - private bool _groupByDiscovery; - - public SqlRemappingVisitor( - Dictionary mappings, - SelectExpression subquery, - TableReferenceExpression tableReferenceExpression) - { - _subquery = subquery; - _tableReferenceExpression = tableReferenceExpression; - _mappings = mappings; - _groupByDiscovery = subquery._groupBy.Count > 0; - _correlatedTerms = new HashSet(ReferenceEqualityComparer.Instance); - } + private readonly SelectExpression _subquery = subquery; + private readonly string _tableAlias = tableAlias; + private readonly Dictionary _mappings = mappings; + private readonly HashSet _correlatedTerms = new(ReferenceEqualityComparer.Instance); + private bool _groupByDiscovery = subquery._groupBy.Count > 0; [return: NotNullIfNotNull("sqlExpression")] public SqlExpression? Remap(SqlExpression? sqlExpression) @@ -204,8 +196,7 @@ when _mappings.TryGetValue(sqlExpression, out var outer): return outer; case ColumnExpression columnExpression - when _groupByDiscovery - && _subquery.ContainsTableReference(columnExpression): + when _groupByDiscovery && _subquery.ContainsReferencedTable(columnExpression): _correlatedTerms.Add(columnExpression); return columnExpression; @@ -213,14 +204,13 @@ when _groupByDiscovery when !_groupByDiscovery && sqlExpression is not SqlConstantExpression and not SqlParameterExpression && _correlatedTerms.Contains(sqlExpression): - var outerColumn = _subquery.GenerateOuterColumn(_tableReferenceExpression, sqlExpression); + var outerColumn = _subquery.GenerateOuterColumn(_tableAlias, sqlExpression); _mappings[sqlExpression] = outerColumn; return outerColumn; case ColumnExpression columnExpression - when !_groupByDiscovery - && _subquery.ContainsTableReference(columnExpression): - var outerColumn1 = _subquery.GenerateOuterColumn(_tableReferenceExpression, columnExpression); + when !_groupByDiscovery && _subquery.ContainsReferencedTable(columnExpression): + var outerColumn1 = _subquery.GenerateOuterColumn(_tableAlias, columnExpression); _mappings[columnExpression] = outerColumn1; return outerColumn1; @@ -270,76 +260,6 @@ public EnclosingTermFindingVisitor(HashSet correlatedTerms) } } - private sealed class TableReferenceUpdatingExpressionVisitor : ExpressionVisitor - { - private readonly SelectExpression _oldSelect; - private readonly SelectExpression _newSelect; - - public TableReferenceUpdatingExpressionVisitor(SelectExpression oldSelect, SelectExpression newSelect) - { - _oldSelect = oldSelect; - _newSelect = newSelect; - } - - [return: NotNullIfNotNull("expression")] - public override Expression? Visit(Expression? expression) - { - if (expression is TableReferenceExpression tableReferenceExpression) - { - tableReferenceExpression.UpdateTableReference(_oldSelect, _newSelect); - } - - return base.Visit(expression); - } - } - - // Note: this is conceptually the same as ColumnExpressionReplacingExpressionVisitor; I duplicated it since this is for a patch, - // and we want to limit the potential risk (note that this calls the special SelectExpression.VisitChildren() with updateColumns: false, - // to avoid infinite recursion). - private sealed class ColumnTableReferenceUpdater : ExpressionVisitor - { - private readonly SelectExpression _oldSelect; - private readonly SelectExpression _newSelect; - - public ColumnTableReferenceUpdater(SelectExpression oldSelect, SelectExpression newSelect) - { - _oldSelect = oldSelect; - _newSelect = newSelect; - } - - [return: NotNullIfNotNull("expression")] - public override Expression? Visit(Expression? expression) - { - if (expression is ConcreteColumnExpression columnExpression - && _oldSelect._tableReferences.Find(t => ReferenceEquals(t.Table, columnExpression.Table)) is TableReferenceExpression - oldTableReference - && _newSelect._tableReferences.Find(t => t.Alias == columnExpression.TableAlias) is TableReferenceExpression - newTableReference - && newTableReference != oldTableReference) - { - return new ConcreteColumnExpression( - columnExpression.Name, - newTableReference, - columnExpression.Type, - columnExpression.TypeMapping!, - columnExpression.IsNullable); - } - - return base.Visit(expression); - } - - protected override Expression VisitExtension(Expression node) - { - if (node is SelectExpression select) - { - Check.DebugAssert(!select._mutable, "Visiting mutable select expression in ColumnTableReferenceUpdater"); - return select.VisitChildren(this, updateColumns: false); - } - - return base.VisitExtension(node); - } - } - private sealed class IdentifierComparer : IEqualityComparer<(ColumnExpression Column, ValueComparer Comparer)> { public bool Equals((ColumnExpression Column, ValueComparer Comparer) x, (ColumnExpression Column, ValueComparer Comparer) y) @@ -349,102 +269,6 @@ public int GetHashCode((ColumnExpression Column, ValueComparer Comparer) obj) => obj.Column.GetHashCode(); } - private sealed class ConcreteColumnExpression : ColumnExpression - { - private readonly TableReferenceExpression _table; - - public ConcreteColumnExpression(IProperty property, IColumnBase column, TableReferenceExpression table, bool nullable) - : this( - column.Name, - table, - property.ClrType.UnwrapNullableType(), - column.PropertyMappings.First(m => m.Property == property).TypeMapping, - nullable || column.IsNullable) - { - } - - public ConcreteColumnExpression(ProjectionExpression subqueryProjection, TableReferenceExpression table) - : this( - subqueryProjection.Alias, table, - subqueryProjection.Type, subqueryProjection.Expression.TypeMapping!, - IsNullableProjection(subqueryProjection)) - { - } - - private static bool IsNullableProjection(ProjectionExpression projectionExpression) - => projectionExpression.Expression switch - { - ColumnExpression columnExpression => columnExpression.IsNullable, - SqlConstantExpression sqlConstantExpression => sqlConstantExpression.Value == null, - _ => true - }; - - public ConcreteColumnExpression( - string name, - TableReferenceExpression table, - Type type, - RelationalTypeMapping? typeMapping, - bool nullable) - : base(type, typeMapping) - { - Name = name; - _table = table; - IsNullable = nullable; - } - - public override string Name { get; } - - public override TableExpressionBase Table - => _table.Table; - - public override string TableAlias - => _table.Alias; - - public override bool IsNullable { get; } - - /// - protected override Expression VisitChildren(ExpressionVisitor visitor) - { - // We only need to visit the table reference expression since TableReferenceUpdatingExpressionVisitor may need to modify it; it - // mutates TableReferenceExpression (a new TableReferenceExpression is never returned). - var newTable = (TableReferenceExpression)visitor.Visit(_table); - Check.DebugAssert(newTable == _table, $"New {nameof(TableReferenceExpression)} returned during visitation!"); - - return this; - } - - public override ConcreteColumnExpression MakeNullable() - => IsNullable ? this : new ConcreteColumnExpression(Name, _table, Type, TypeMapping, true); - - public override SqlExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping) - => new ConcreteColumnExpression(Name, _table, Type, typeMapping, IsNullable); - - internal void Verify(IReadOnlyList tableReferences) - { - if (!tableReferences.Contains(_table, ReferenceEqualityComparer.Instance)) - { - throw new InvalidOperationException("Dangling column."); - } - } - - /// - public override bool Equals(object? obj) - => obj != null - && (ReferenceEquals(this, obj) - || obj is ConcreteColumnExpression concreteColumnExpression - && Equals(concreteColumnExpression)); - - private bool Equals(ConcreteColumnExpression concreteColumnExpression) - => base.Equals(concreteColumnExpression) - && Name == concreteColumnExpression.Name - && _table.Equals(concreteColumnExpression._table) - && IsNullable == concreteColumnExpression.IsNullable; - - /// - public override int GetHashCode() - => HashCode.Combine(base.GetHashCode(), Name, _table, IsNullable); - } - private struct SingleCollectionInfo { public SingleCollectionInfo( @@ -580,175 +404,38 @@ public ClientProjectionRemappingExpressionVisitor(List clientProjectionI } } - private sealed class SelectExpressionVerifyingExpressionVisitor : ExpressionVisitor + // We sometimes clone when the result will be integrated in the same query tree (e.g. GroupBy - this needs to be reviewed and hopefully + // improved); for those cases SqlAliasManager is passed in and ensures unique table aliases across the entire query. + // But for split query, we clone in order to create a completely separate query, in which case we don't want unique aliases - and so + // SqlAliasManager isn't passed in. + private sealed class CloningExpressionVisitor(SqlAliasManager? sqlAliasManager) : ExpressionVisitor { - private readonly List _tableReferencesInScope = []; - - public SelectExpressionVerifyingExpressionVisitor(IEnumerable tableReferencesInScope) - { - _tableReferencesInScope.AddRange(tableReferencesInScope); - } + private readonly Dictionary _tableAliasMap = new(); [return: NotNullIfNotNull("expression")] public override Expression? Visit(Expression? expression) { switch (expression) { - case SelectExpression selectExpression: - foreach (var tableReference in selectExpression._tableReferences) - { - tableReference.Verify(selectExpression); - } - - var currentLevelTableReferences = new List(); - for (var i = 0; i < selectExpression._tables.Count; i++) - { - var table = selectExpression._tables[i]; - var tableReference = selectExpression._tableReferences[i]; - switch (table) - { - case PredicateJoinExpressionBase predicateJoinExpressionBase: - Verify(predicateJoinExpressionBase.Table, _tableReferencesInScope); - currentLevelTableReferences.Add(tableReference); - Verify( - predicateJoinExpressionBase.JoinPredicate, - _tableReferencesInScope.Concat(currentLevelTableReferences)); - break; - - case SelectExpression innerSelectExpression: - Verify(innerSelectExpression, _tableReferencesInScope); - break; - - case CrossApplyExpression crossApplyExpression: - Verify(crossApplyExpression, _tableReferencesInScope.Concat(currentLevelTableReferences)); - break; - - case OuterApplyExpression outerApplyExpression: - Verify(outerApplyExpression, _tableReferencesInScope.Concat(currentLevelTableReferences)); - break; - - case JoinExpressionBase joinExpressionBase: - Verify(joinExpressionBase.Table, _tableReferencesInScope); - break; - - case SetOperationBase setOperationBase: - Verify(setOperationBase.Source1, _tableReferencesInScope); - Verify(setOperationBase.Source2, _tableReferencesInScope); - break; - } - - if (table is not PredicateJoinExpressionBase) - { - currentLevelTableReferences.Add(tableReference); - } - } - - _tableReferencesInScope.AddRange(currentLevelTableReferences); - - foreach (var projection in selectExpression._projection) - { - Visit(projection); - } - - foreach (var keyValuePair in selectExpression._projectionMapping) - { - Visit(keyValuePair.Value); - } - - foreach (var clientProjection in selectExpression._clientProjections) - { - Visit(clientProjection); - } - - foreach (var grouping in selectExpression._groupBy) - { - Visit(grouping); - } - - foreach (var ordering in selectExpression._orderings) - { - Visit(ordering); - } - - Visit(selectExpression.Predicate); - Visit(selectExpression.Having); - Visit(selectExpression.Offset); - Visit(selectExpression.Limit); - - foreach (var identifier in selectExpression._identifier) - { - Visit(identifier.Column); - } - - foreach (var childIdentifier in selectExpression._childIdentifiers) + case TableExpressionBase table: + { + if (sqlAliasManager is null || table.Alias is null) { - Visit(childIdentifier.Column); + return table.Clone(table.Alias, this); } - return selectExpression; + var newTableAlias = sqlAliasManager.GenerateTableAlias(table.Alias); + _tableAliasMap[table.Alias] = newTableAlias; + return table.Clone(newTableAlias, this); + } - case ConcreteColumnExpression concreteColumnExpression: - concreteColumnExpression.Verify(_tableReferencesInScope); - return concreteColumnExpression; + case ColumnExpression column when _tableAliasMap.TryGetValue(column.TableAlias, out var newTableAlias): + return new ColumnExpression(column.Name, newTableAlias, column.Type, column.TypeMapping, column.IsNullable); - case ShapedQueryExpression shapedQueryExpression: - Verify(shapedQueryExpression.QueryExpression, _tableReferencesInScope); - return shapedQueryExpression; + default: + return base.Visit(expression); } - - return base.Visit(expression); } - - private static void Verify(Expression expression, IEnumerable tableReferencesInScope) - => new SelectExpressionVerifyingExpressionVisitor(tableReferencesInScope) - .Visit(expression); - } - - // We sometimes clone when the result will be integrated in the same query tree (e.g. GroupBy - this needs to be reviewed and hopefully - // improved); for those cases SqlAliasManager is passed in and ensures unique table aliases across the entire query. - // But for split query, we clone in order to create a completely separate query, in which case we don't want unique aliases - and so - // SqlAliasManager isn't passed in. - private sealed class CloningExpressionVisitor(SqlAliasManager? sqlAliasManager) : ExpressionVisitor - { - [return: NotNullIfNotNull("expression")] - public override Expression? Visit(Expression? expression) - => expression switch - { - TableExpressionBase table - => table.Clone( - sqlAliasManager is null || table.Alias is null - ? table.Alias - : sqlAliasManager.GenerateTableAlias(table.Alias), this), - - _ => base.Visit(expression) - }; - } - - private sealed class ColumnExpressionReplacingExpressionVisitor : ExpressionVisitor - { - private readonly SelectExpression _oldSelectExpression; - private readonly List _newTableReferences; - - public ColumnExpressionReplacingExpressionVisitor( - SelectExpression oldSelectExpression, - IEnumerable newTableReferences) - { - _oldSelectExpression = oldSelectExpression; - _newTableReferences = newTableReferences.ToList(); - } - - [return: NotNullIfNotNull("expression")] - public override Expression? Visit(Expression? expression) - => expression is ConcreteColumnExpression concreteColumnExpression - && _oldSelectExpression.Tables.IndexOf(concreteColumnExpression.Table) is var index - && index > -1 - ? new ConcreteColumnExpression( - concreteColumnExpression.Name, - _newTableReferences[index], - concreteColumnExpression.Type, - concreteColumnExpression.TypeMapping!, - concreteColumnExpression.IsNullable) - : base.Visit(expression); } private sealed class TpcTableExpressionRemovingExpressionVisitor : ExpressionVisitor @@ -785,8 +472,7 @@ public TpcTableExpressionRemovingExpressionVisitor(SqlAliasManager sqlAliasManag foreach (var kvp in selectExpression._tpcDiscriminatorValues) { var tpcTablesExpression = kvp.Key; - var subSelectExpressions = tpcTablesExpression.Prune(kvp.Value.Item2).SelectExpressions - .Select(AssignUniqueAliasToTable).ToList(); + var subSelectExpressions = tpcTablesExpression.Prune(kvp.Value.Item2).SelectExpressions; var firstSelectExpression = subSelectExpressions[0]; // There will be at least one. int[]? reindexingMap = null; @@ -834,14 +520,12 @@ public TpcTableExpressionRemovingExpressionVisitor(SqlAliasManager sqlAliasManag var generatedSelectExpression = new SelectExpression(alias: null, _sqlAliasManager); var unionExpression = new UnionExpression(setOperationAlias, source1, source2, distinct: false); - var tableReferenceExpression = new TableReferenceExpression(generatedSelectExpression, setOperationAlias); generatedSelectExpression._tables.Add(unionExpression); - generatedSelectExpression._tableReferences.Add(tableReferenceExpression); foreach (var projection in result.Projection) { generatedSelectExpression._projection.Add( new ProjectionExpression( - new ConcreteColumnExpression(projection, tableReferenceExpression), projection.Alias)); + CreateColumnExpression(projection, setOperationAlias), projection.Alias)); } generatedSelectExpression._mutable = false; @@ -866,22 +550,11 @@ public TpcTableExpressionRemovingExpressionVisitor(SqlAliasManager sqlAliasManag { result.Alias = tpcTablesExpression.Alias; var tableIndex = - selectExpression._tables.FindIndex(teb => ReferenceEquals(UnwrapJoinExpression(teb), tpcTablesExpression)); + selectExpression._tables.FindIndex(teb => ReferenceEquals(teb.UnwrapJoin(), tpcTablesExpression)); var table = selectExpression._tables[tableIndex]; selectExpression._tables[tableIndex] = (TableExpressionBase)ReplacingExpressionVisitor.Replace( tpcTablesExpression, result, table); } - - SelectExpression AssignUniqueAliasToTable(SelectExpression se) - { - // we assign unique alias to inner tables here so that we can avoid wasting aliases on pruned tables - var table = se._tables[0]; - var alias = _sqlAliasManager.GenerateTableAlias(table.Alias!); - table.Alias = alias; - se._tableReferences[0].Alias = alias; - - return se; - } } selectExpression._tpcDiscriminatorValues.Clear(); diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index d350b444aa6..d037a9d00f9 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -29,7 +29,6 @@ public sealed partial class SelectExpression : TableExpressionBase private readonly List _projection = []; private readonly List _tables = []; - private readonly List _tableReferences = []; private readonly List _groupBy = []; private readonly List _orderings = []; @@ -56,12 +55,10 @@ public sealed partial class SelectExpression : TableExpressionBase // Pushdown should null it out as if GroupBy was present was pushed down. private List<(ColumnExpression Column, ValueComparer Comparer)>? _preGroupByIdentifier; - private SelectExpression( string? alias, List projections, List tables, - List tableReferences, List groupBy, List orderings, IEnumerable annotations, @@ -70,7 +67,6 @@ private SelectExpression( { _projection = projections; _tables = tables; - _tableReferences = tableReferences; _groupBy = groupBy; _orderings = orderings; @@ -122,12 +118,12 @@ public SelectExpression( { _sqlAliasManager = sqlAliasManager; - var tableReferenceExpression = new TableReferenceExpression(this, tableExpression.Alias!); - AddTable(tableExpression, tableReferenceExpression); + _tables.Add(tableExpression); + var tableAlias = tableExpression.GetRequiredAlias(); - var columnExpression = new ConcreteColumnExpression( + var columnExpression = new ColumnExpression( columnName, - tableReferenceExpression, + tableAlias, columnType.UnwrapNullableType(), columnTypeMapping, isColumnNullable ?? columnType.IsNullableType()); @@ -136,9 +132,9 @@ public SelectExpression( if (identifierColumnName != null && identifierColumnType != null && identifierColumnTypeMapping != null) { - var identifierColumn = new ConcreteColumnExpression( + var identifierColumn = new ColumnExpression( identifierColumnName, - tableReferenceExpression, + tableAlias, identifierColumnType.UnwrapNullableType(), identifierColumnTypeMapping, identifierColumnType.IsNullableType()); @@ -167,24 +163,23 @@ internal SelectExpression( { var keyProperties = entityType.FindPrimaryKey()!.Properties; List joinColumns = default!; - var tableMap = new Dictionary(); + var tableMap = new Dictionary(); var columns = new Dictionary(); foreach (var baseType in entityType.GetAllBaseTypesInclusive()) { var table = GetTableBaseFiltered(baseType, tableMap); var alias = _sqlAliasManager.GenerateTableAlias(table); var tableExpression = new TableExpression(alias, table); - var tableReferenceExpression = new TableReferenceExpression(this, alias); - tableMap.Add(table, tableReferenceExpression); + tableMap.Add(table, alias); foreach (var property in baseType.GetDeclaredProperties()) { - columns[property] = CreateColumnExpression(property, table, tableReferenceExpression, nullable: false); + columns[property] = CreateColumnExpression(property, table, alias, nullable: false); } if (_tables.Count == 0) { - AddTable(tableExpression, tableReferenceExpression); + _tables.Add(tableExpression); joinColumns = []; foreach (var property in keyProperties) { @@ -196,14 +191,13 @@ internal SelectExpression( else { var innerColumns = keyProperties.Select( - p => CreateColumnExpression(p, table, tableReferenceExpression, nullable: false)); + p => CreateColumnExpression(p, table, alias, nullable: false)); var joinPredicate = joinColumns .Zip(innerColumns, sqlExpressionFactory.Equal) .Aggregate(sqlExpressionFactory.AndAlso); - var joinExpression = new InnerJoinExpression(tableExpression, joinPredicate); - AddTable(joinExpression, tableReferenceExpression); + _tables.Add(new InnerJoinExpression(tableExpression, joinPredicate)); } } @@ -213,16 +207,14 @@ internal SelectExpression( var table = GetTableBaseFiltered(derivedType, tableMap); var alias = _sqlAliasManager.GenerateTableAlias(table); var tableExpression = new TableExpression(alias, table); - var tableReferenceExpression = new TableReferenceExpression(this, alias); - tableMap.Add(table, tableReferenceExpression); + tableMap.Add(table, alias); foreach (var property in derivedType.GetDeclaredProperties()) { - columns[property] = CreateColumnExpression(property, table, tableReferenceExpression, nullable: true); + columns[property] = CreateColumnExpression(property, table, alias, nullable: true); } - var keyColumns = keyProperties.Select(p => CreateColumnExpression(p, table, tableReferenceExpression, nullable: true)) - .ToArray(); + var keyColumns = keyProperties.Select(p => CreateColumnExpression(p, table, alias, nullable: true)).ToArray(); if (!derivedType.IsAbstract()) { @@ -236,8 +228,7 @@ internal SelectExpression( .Zip(keyColumns, sqlExpressionFactory.Equal) .Aggregate(sqlExpressionFactory.AndAlso); - var joinExpression = new LeftJoinExpression(tableExpression, joinPredicate, prunable: true); - AddTable(joinExpression, tableReferenceExpression); + _tables.Add(new LeftJoinExpression(tableExpression, joinPredicate, prunable: true)); } caseWhenClauses.Reverse(); @@ -260,15 +251,13 @@ _projectionMapping[new ProjectionMember()] = // For single entity case, we don't need discriminator. var table = entityTypes[0].GetViewOrTableMappings().Single().Table; var alias = _sqlAliasManager.GenerateTableAlias(table); - var tableExpression = new TableExpression(alias, table); - var tableReferenceExpression = new TableReferenceExpression(this, alias); - var tableMap = new Dictionary { [table] = tableReferenceExpression }; - AddTable(tableExpression, tableReferenceExpression); + var tableMap = new Dictionary { [table] = alias }; + _tables.Add(new TableExpression(alias, table)); var propertyExpressions = new Dictionary(); foreach (var property in GetAllPropertiesInHierarchy(entityType)) { - propertyExpressions[property] = CreateColumnExpression(property, table, tableReferenceExpression, nullable: false); + propertyExpressions[property] = CreateColumnExpression(property, table, alias, nullable: false); } _projectionMapping[new ProjectionMember()] = @@ -336,17 +325,14 @@ _projectionMapping[new ProjectionMember()] = var table = tables[i]; var selectExpression = new SelectExpression(alias: null, _sqlAliasManager); var alias = _sqlAliasManager.GenerateTableAlias(table); - var tableExpression = new TableExpression(alias, table); - var tableReferenceExpression = new TableReferenceExpression(selectExpression, alias); - selectExpression._tables.Add(tableExpression); - selectExpression._tableReferences.Add(tableReferenceExpression); + selectExpression._tables.Add(new TableExpression(alias, table)); for (var j = 0; j < properties.Length; j++) { var property = properties[j]; var declaringEntityType = property.DeclaringType.ContainingEntityType; var projection = declaringEntityType.IsAssignableFrom(concreteEntityType) - ? CreateColumnExpression(property, table, tableReferenceExpression, declaringEntityType != entityType) + ? CreateColumnExpression(property, table, alias, declaringEntityType != entityType) : (SqlExpression)sqlExpressionFactory.Constant( null, property.ClrType.MakeNullable(), property.GetRelationalTypeMapping()); selectExpression._projection.Add(new ProjectionExpression(projection, propertyNames[j])); @@ -361,17 +347,14 @@ _projectionMapping[new ProjectionMember()] = selectExpression._mutable = false; } - // We only assign unique alias to Tpc var tableAlias = _sqlAliasManager.GenerateTableAlias("t"); var tpcTables = new TpcTablesExpression(tableAlias, entityType, subSelectExpressions); - var tpcTableReference = new TableReferenceExpression(this, tableAlias); _tables.Add(tpcTables); - _tableReferences.Add(tpcTableReference); var firstSelectExpression = subSelectExpressions[0]; var columns = new Dictionary(); for (var i = 0; i < properties.Length; i++) { - columns[properties[i]] = new ConcreteColumnExpression(firstSelectExpression._projection[i], tpcTableReference); + columns[properties[i]] = CreateColumnExpression(firstSelectExpression._projection[i], tableAlias); } foreach (var property in entityType.FindPrimaryKey()!.Properties) @@ -380,9 +363,9 @@ _projectionMapping[new ProjectionMember()] = _identifier.Add((columnExpression, property.GetKeyValueComparer())); } - var discriminatorColumn = new ConcreteColumnExpression(firstSelectExpression._projection[^1], tpcTableReference); + var discriminatorColumn = CreateColumnExpression(firstSelectExpression._projection[^1], tableAlias); _tpcDiscriminatorValues[tpcTables] = (discriminatorColumn, discriminatorValues); - var tableMap = tables.ToDictionary(t => t, _ => tpcTableReference); + var tableMap = tables.ToDictionary(t => t, _ => tableAlias); _projectionMapping[new ProjectionMember()] = new StructuralTypeProjectionExpression(entityType, columns, tableMap, nullable: false, discriminatorColumn); @@ -418,23 +401,21 @@ _projectionMapping[new ProjectionMember()] = var keyProperties = entityType.FindPrimaryKey()!.Properties; List joinColumns = default!; var columns = new Dictionary(); - var tableReferenceExpressionMap = new Dictionary(); + var tableReferenceExpressionMap = new Dictionary(); foreach (var mapping in mappings) { var table = mapping.Table; var alias = _sqlAliasManager.GenerateTableAlias(table); var tableExpression = new TableExpression(alias, table); - var tableReferenceExpression = new TableReferenceExpression(this, alias); - tableReferenceExpressionMap[table] = tableReferenceExpression; + tableReferenceExpressionMap[table] = alias; if (_tables.Count == 0) { - AddTable(tableExpression, tableReferenceExpression); + _tables.Add(tableExpression); joinColumns = []; foreach (var property in keyProperties) { - var columnExpression = CreateColumnExpression( - property, table, tableReferenceExpression, nullable: false); + var columnExpression = CreateColumnExpression(property, table, alias, nullable: false); columns[property] = columnExpression; joinColumns.Add(columnExpression); _identifier.Add((columnExpression, property.GetKeyValueComparer())); @@ -442,15 +423,13 @@ _projectionMapping[new ProjectionMember()] = } else { - var innerColumns = keyProperties.Select( - p => CreateColumnExpression(p, table, tableReferenceExpression, nullable: false)); + var innerColumns = keyProperties.Select(p => CreateColumnExpression(p, table, alias, nullable: false)); var joinPredicate = joinColumns .Zip(innerColumns, sqlExpressionFactory.Equal) .Aggregate(sqlExpressionFactory.AndAlso); - var joinExpression = new InnerJoinExpression(tableExpression, joinPredicate, prunable: true); - AddTable(joinExpression, tableReferenceExpression); + _tables.Add(new InnerJoinExpression(tableExpression, joinPredicate, prunable: true)); } } @@ -477,21 +456,21 @@ _projectionMapping[new ProjectionMember()] = void GenerateNonHierarchyNonSplittingEntityType(ITableBase table, TableExpressionBase tableExpression) { - var tableReferenceExpression = new TableReferenceExpression(this, tableExpression.Alias!); - AddTable(tableExpression, tableReferenceExpression); + _tables.Add(tableExpression); + var alias = tableExpression.Alias!; var propertyExpressions = new Dictionary(); foreach (var property in GetAllPropertiesInHierarchy(entityType)) { - propertyExpressions[property] = CreateColumnExpression(property, table, tableReferenceExpression, nullable: false); + propertyExpressions[property] = CreateColumnExpression(property, table, alias, nullable: false); } var projection = new StructuralTypeProjectionExpression( entityType, propertyExpressions, - new Dictionary { [table] = tableReferenceExpression }); + new Dictionary { [table] = alias }); - AddJsonNavigationBindings(entityType, projection, propertyExpressions, tableReferenceExpression); + AddJsonNavigationBindings(entityType, projection, propertyExpressions, alias); _projectionMapping[new ProjectionMember()] = projection; var primaryKey = entityType.FindPrimaryKey(); @@ -504,14 +483,11 @@ void GenerateNonHierarchyNonSplittingEntityType(ITableBase table, TableExpressio } } - static ITableBase GetTableBaseFiltered(IEntityType entityType, Dictionary existingTables) + static ITableBase GetTableBaseFiltered(IEntityType entityType, Dictionary existingTables) => entityType.GetViewOrTableMappings().Single(m => !existingTables.ContainsKey(m.Table)).Table; } - internal SelectExpression( - IEntityType entityType, - TableExpressionBase tableExpressionBase, - SqlAliasManager sqlAliasManager) + internal SelectExpression(IEntityType entityType, TableExpressionBase tableExpressionBase, SqlAliasManager sqlAliasManager) : base(null) { _sqlAliasManager = sqlAliasManager; @@ -525,19 +501,19 @@ internal SelectExpression( var table = (tableExpressionBase as ITableBasedExpression)?.Table; Check.DebugAssert(table is not null, "SelectExpression with unexpected missing table"); - var tableReferenceExpression = new TableReferenceExpression(this, tableExpressionBase.Alias!); - var tableMap = new Dictionary { [table] = tableReferenceExpression }; - AddTable(tableExpressionBase, tableReferenceExpression); + var alias = tableExpressionBase.Alias!; + var tableMap = new Dictionary { [table] = alias }; + _tables.Add(tableExpressionBase); var propertyExpressions = new Dictionary(); foreach (var property in GetAllPropertiesInHierarchy(entityType)) { - propertyExpressions[property] = CreateColumnExpression(property, table, tableReferenceExpression, nullable: false); + propertyExpressions[property] = CreateColumnExpression(property, table, alias, nullable: false); } var projection = new StructuralTypeProjectionExpression(entityType, propertyExpressions, tableMap); - AddJsonNavigationBindings(entityType, projection, propertyExpressions, tableReferenceExpression); + AddJsonNavigationBindings(entityType, projection, propertyExpressions, alias); _projectionMapping[new ProjectionMember()] = projection; var primaryKey = entityType.FindPrimaryKey(); @@ -579,8 +555,8 @@ public SelectExpression( entityType.BaseType is null && !entityType.GetDirectlyDerivedTypes().Any(), "Inheritance encountered inside a JSON document"); - var tableReferenceExpression = new TableReferenceExpression(this, tableExpressionBase.Alias!); - AddTable(tableExpressionBase, tableReferenceExpression); + var tableAlias = tableExpressionBase.Alias!; + _tables.Add(tableExpressionBase); // Create a dictionary mapping all properties to their ColumnExpressions, for the SelectExpression's projection. var propertyExpressions = new Dictionary(); @@ -607,7 +583,7 @@ public SelectExpression( var table = entityType.GetViewOrTableMappings().SingleOrDefault()?.Table ?? entityType.GetDefaultMappings().Single().Table; // TODO: We'll need to make sure this is correct when we add support for JSON complex types. - var tableMap = new Dictionary { [table] = tableReferenceExpression }; + var tableMap = new Dictionary { [table] = tableAlias }; var projection = new StructuralTypeProjectionExpression( entityType, @@ -632,9 +608,9 @@ public SelectExpression( // The TableExpressionBase represents a relational expansion of the JSON collection. We now need a ColumnExpression to represent // the specific JSON property (projected as a relational column) which holds the JSON subtree for the target entity. - var column = new ConcreteColumnExpression( + var column = new ColumnExpression( jsonNavigationName, - tableReferenceExpression, + tableAlias, containerColumnTypeMapping.ClrType, containerColumnTypeMapping, isNullable); @@ -664,9 +640,9 @@ public SelectExpression( _projectionMapping[new ProjectionMember()] = projection; - var identifierColumn = new ConcreteColumnExpression( + var identifierColumn = new ColumnExpression( identifierColumnName, - tableReferenceExpression, + tableAlias, identifierColumnType.UnwrapNullableType(), identifierColumnTypeMapping, identifierColumnType.IsNullableType()); @@ -678,7 +654,7 @@ private void AddJsonNavigationBindings( IEntityType entityType, StructuralTypeProjectionExpression projection, Dictionary propertyExpressions, - TableReferenceExpression tableReferenceExpression) + string tableAlias) { foreach (var ownedJsonNavigation in GetAllNavigationsInHierarchy(entityType) .Where( @@ -696,9 +672,9 @@ private void AddJsonNavigationBindings( || !ownedJsonNavigation.ForeignKey.IsRequiredDependent || ownedJsonNavigation.IsCollection; - var column = new ConcreteColumnExpression( + var column = new ColumnExpression( containerColumnName, - tableReferenceExpression, + tableAlias, containerColumnTypeMapping.ClrType, containerColumnTypeMapping, isNullable); @@ -1436,10 +1412,6 @@ static Expression RemoveConvert(Expression expression) if (querySplittingBehavior == QuerySplittingBehavior.SplitQuery) { var outerSelectExpression = (SelectExpression)cloningExpressionVisitor!.Visit(baseSelectExpression!); - innerSelectExpression = - (SelectExpression)new ColumnExpressionReplacingExpressionVisitor( - this, outerSelectExpression._tableReferences) - .Visit(innerSelectExpression); if (outerSelectExpression.Limit != null || outerSelectExpression.Offset != null @@ -1461,11 +1433,7 @@ static Expression RemoveConvert(Expression expression) { orderingsToBeErased = innerSelectExpression.Orderings.ToList(); } -#if DEBUG - Check.DebugAssert( - !(new SelectExpressionCorrelationFindingExpressionVisitor(this) - .ContainsOuterReference(innerSelectExpression)), "Split query contains outer reference"); -#endif + var parentIdentifier = GetIdentifierAccessor(this, newClientProjections, actualParentIdentifier).Item1; outerSelectExpression.AddJoin( @@ -1485,7 +1453,6 @@ static Expression RemoveConvert(Expression expression) if (containsOrdering) { var collectionJoinedInnerTable = ((JoinExpressionBase)innerSelectExpression._tables[^1]).Table; - var collectionJoinedTableReference = innerSelectExpression._tableReferences[^1]; var innerOrderingExpressions = new List(); if (orderingsToBeErased != null) { @@ -1498,7 +1465,8 @@ static Expression RemoveConvert(Expression expression) { innerOrderingExpressions.Add( new OrderingExpression( - subquery.GenerateOuterColumn(collectionJoinedTableReference, ordering.Expression), + subquery.GenerateOuterColumn( + collectionJoinedInnerTable.GetRequiredAlias(), ordering.Expression), ordering.IsAscending)); } } @@ -1512,10 +1480,7 @@ static Expression RemoveConvert(Expression expression) else { // If orderings were not erased then they must be present in inner - GetOrderingsFromInnerTable( - collectionJoinedInnerTable, - collectionJoinedTableReference, - innerOrderingExpressions); + GetOrderingsFromInnerTable(collectionJoinedInnerTable, innerOrderingExpressions); } foreach (var ordering in innerOrderingExpressions) @@ -1568,7 +1533,6 @@ static Expression RemoveConvert(Expression expression) if (containsOrdering) { var collectionJoinedInnerTable = innerSelectExpression._tables[0]; - var collectionJoinedTableReference = innerSelectExpression._tableReferences[0]; var innerOrderingExpressions = new List(); if (orderingsToBeErased != null) { @@ -1581,7 +1545,8 @@ static Expression RemoveConvert(Expression expression) { innerOrderingExpressions.Add( new OrderingExpression( - subquery.GenerateOuterColumn(collectionJoinedTableReference, ordering.Expression), + subquery.GenerateOuterColumn( + collectionJoinedInnerTable.GetRequiredAlias(), ordering.Expression), ordering.IsAscending)); } } @@ -1595,10 +1560,7 @@ static Expression RemoveConvert(Expression expression) else { // If orderings were not erased then they must be present in inner - GetOrderingsFromInnerTable( - collectionJoinedInnerTable, - collectionJoinedTableReference, - innerOrderingExpressions); + GetOrderingsFromInnerTable(collectionJoinedInnerTable, innerOrderingExpressions); } foreach (var ordering in innerOrderingExpressions) @@ -1699,11 +1661,10 @@ static Expression RemoveConvert(Expression expression) return shaperExpression; - void GetOrderingsFromInnerTable( - TableExpressionBase tableExpressionBase, - TableReferenceExpression tableReferenceExpression, - List orderings) + void GetOrderingsFromInnerTable(TableExpressionBase tableExpressionBase, List orderings) { + var tableAlias = tableExpressionBase.GetRequiredAlias(); + // If operation was converted to predicate join (inner/left join), then ordering will be in a RowNumberExpression if (tableExpressionBase is SelectExpression { @@ -1713,14 +1674,14 @@ void GetOrderingsFromInnerTable( && rowNumberSubquery.Projection.Select(pe => pe.Expression) .OfType().SingleOrDefault() is RowNumberExpression rowNumberExpression) { - var rowNumberSubqueryTableReference = joinedSubquery._tableReferences.Single(); + var rowNumberSubqueryTableAlias = joinedSubquery.Tables.Single().GetRequiredAlias(); foreach (var partition in rowNumberExpression.Partitions) { orderings.Add( new OrderingExpression( joinedSubquery.GenerateOuterColumn( - tableReferenceExpression, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, partition)), + tableAlias, + rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableAlias, partition)), ascending: true)); } @@ -1729,8 +1690,8 @@ void GetOrderingsFromInnerTable( orderings.Add( new OrderingExpression( joinedSubquery.GenerateOuterColumn( - tableReferenceExpression, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, ordering.Expression)), + tableAlias, + rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableAlias, ordering.Expression)), ordering.IsAscending)); } } @@ -1741,7 +1702,7 @@ void GetOrderingsFromInnerTable( { orderings.Add( new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn(tableReferenceExpression, ordering.Expression), + collectionSelectExpression.GenerateOuterColumn(tableAlias, ordering.Expression), ordering.IsAscending)); } } @@ -2106,10 +2067,11 @@ public void ApplyPredicate(SqlExpression sqlExpression) case SqlBinaryExpression { OperatorType: ExpressionType.Equal, - Left: ColumnExpression { Table: TpcTablesExpression leftTpc } leftColumn, + Left: ColumnExpression leftColumn, Right: SqlConstantExpression { Value: string s1 } } - when _tpcDiscriminatorValues.TryGetValue(leftTpc, out var leftTuple) && leftTuple.Item1.Equals(leftColumn): + when GetTable(leftColumn) is TpcTablesExpression leftTpc + && _tpcDiscriminatorValues.TryGetValue(leftTpc, out var leftTuple) && leftTuple.Item1.Equals(leftColumn): { var newList = leftTuple.Item2.Intersect(new List { s1 }).ToList(); if (newList.Count > 0) @@ -2125,9 +2087,10 @@ when _tpcDiscriminatorValues.TryGetValue(leftTpc, out var leftTuple) && leftTupl { OperatorType: ExpressionType.Equal, Left: SqlConstantExpression { Value: string s2 }, - Right: ColumnExpression { Table: TpcTablesExpression rightTpc } rightColumn + Right: ColumnExpression rightColumn } - when _tpcDiscriminatorValues.TryGetValue(rightTpc, out var rightTuple) + when GetTable(rightColumn) is TpcTablesExpression rightTpc + && _tpcDiscriminatorValues.TryGetValue(rightTpc, out var rightTuple) && rightTuple.Item1.Equals(rightColumn): { var newList = rightTuple.Item2.Intersect(new List { s2 }).ToList(); @@ -2144,10 +2107,11 @@ when _tpcDiscriminatorValues.TryGetValue(rightTpc, out var rightTuple) // _tpcDiscriminatorValues (which will be handled later) instead of as a WHERE predicate. case InExpression { - Item: ColumnExpression { Table: TpcTablesExpression itemTpc } itemColumn, + Item: ColumnExpression itemColumn, Values: IReadOnlyList valueExpressions } - when _tpcDiscriminatorValues.TryGetValue(itemTpc, out var itemTuple) + when GetTable(itemColumn) is TpcTablesExpression itemTpc + && _tpcDiscriminatorValues.TryGetValue(itemTpc, out var itemTuple) && itemTuple.Item1.Equals(itemColumn): { var constantValues = new string[valueExpressions.Count]; @@ -2216,13 +2180,12 @@ public void ApplyGrouping(Expression keySelector) var sqlRemappingVisitor = PushdownIntoSubqueryInternal(); var newGroupByTerms = new List(groupByTerms.Count); var subquery = (SelectExpression)_tables[0]; - var subqueryTableReference = _tableReferences[0]; for (var i = 0; i < groupByTerms.Count; i++) { var item = groupByTerms[i]; var newItem = subquery._projection.Any(e => e.Expression.Equals(item)) ? sqlRemappingVisitor.Remap(item) - : subquery.GenerateOuterColumn(subqueryTableReference, item, groupByAliases[i] ?? "Key"); + : subquery.GenerateOuterColumn(subquery.Alias!, item, groupByAliases[i] ?? "Key"); newGroupByTerms.Add(newItem); } @@ -2273,13 +2236,12 @@ public RelationalGroupByShaperExpression ApplyGrouping( var sqlRemappingVisitor = PushdownIntoSubqueryInternal(); var newGroupByTerms = new List(groupByTerms.Count); var subquery = (SelectExpression)_tables[0]; - var subqueryTableReference = _tableReferences[0]; for (var i = 0; i < groupByTerms.Count; i++) { var item = groupByTerms[i]; var newItem = subquery._projection.Any(e => e.Expression.Equals(item)) ? sqlRemappingVisitor.Remap(item) - : subquery.GenerateOuterColumn(subqueryTableReference, item, groupByAliases[i] ?? "Key"); + : subquery.GenerateOuterColumn(subquery.Alias!, item, groupByAliases[i] ?? "Key"); newGroupByTerms.Add(newItem); } @@ -2500,8 +2462,7 @@ private void ApplySetOperation( { // TODO: Introduce clone method? See issue#24460 var select1 = new SelectExpression( - null, [], _tables.ToList(), _tableReferences.ToList(), _groupBy.ToList(), _orderings.ToList(), - GetAnnotations(), _sqlAliasManager) + alias: null, projections: [], _tables.ToList(), _groupBy.ToList(), _orderings.ToList(), GetAnnotations(), _sqlAliasManager) { IsDistinct = IsDistinct, Predicate = Predicate, @@ -2517,7 +2478,6 @@ private void ApplySetOperation( _groupBy.Clear(); _orderings.Clear(); _tables.Clear(); - _tableReferences.Clear(); select1._projectionMapping = new Dictionary(_projectionMapping); _projectionMapping.Clear(); select1._identifier.AddRange(_identifier); @@ -2529,15 +2489,6 @@ private void ApplySetOperation( _tpcDiscriminatorValues.Clear(); - // Remap tableReferences in select1 - foreach (var tableReference in select1._tableReferences) - { - tableReference.UpdateTableReference(this, select1); - } - - var tableReferenceUpdatingExpressionVisitor = new TableReferenceUpdatingExpressionVisitor(this, select1); - tableReferenceUpdatingExpressionVisitor.Visit(select1); - var outerIdentifiers = select1._identifier.Count == select2._identifier.Count ? new ColumnExpression?[select1._identifier.Count] : Array.Empty(); @@ -2582,7 +2533,6 @@ private void ApplySetOperation( } var setOperationAlias = _sqlAliasManager.GenerateTableAlias("t"); - var tableReferenceExpression = new TableReferenceExpression(this, setOperationAlias); foreach (var (projectionMember, expression1, expression2) in select1._projectionMapping.Join( select2._projectionMapping, @@ -2609,7 +2559,7 @@ private void ApplySetOperation( var innerProjection2 = new ProjectionExpression(innerColumn2, projectionAlias); select1._projection.Add(innerProjection1); select2._projection.Add(innerProjection2); - var outerProjection = new ConcreteColumnExpression(innerProjection1, tableReferenceExpression); + var outerProjection = CreateColumnExpression(innerProjection1, setOperationAlias); if (IsNullableProjection(innerProjection1) || IsNullableProjection(innerProjection2)) @@ -2666,7 +2616,6 @@ private void ApplySetOperation( _ => throw new InvalidOperationException(CoreStrings.InvalidSwitch(nameof(setOperationType), setOperationType)) }; _tables.Add(setExpression); - _tableReferences.Add(tableReferenceExpression); select1._projectionMapping.Clear(); select2._projectionMapping.Clear(); @@ -2732,7 +2681,7 @@ void ProcessStructuralType( var innerProjection = new ProjectionExpression(column1, alias); select1._projection.Add(innerProjection); select2._projection.Add(new ProjectionExpression(column2, alias)); - var outerColumn = new ConcreteColumnExpression(innerProjection, tableReferenceExpression); + var outerColumn = CreateColumnExpression(innerProjection, setOperationAlias); if (column1.IsNullable || column2.IsNullable) { @@ -2793,7 +2742,7 @@ void ProcessStructuralType( projection1.TableMap.Keys.All(t => projection2.TableMap.ContainsKey(t)), "Set operation over entity projections with table map discrepancy"); - var tableMap = projection1.TableMap.ToDictionary(kvp => kvp.Key, kvp => tableReferenceExpression); + var tableMap = projection1.TableMap.ToDictionary(kvp => kvp.Key, _ => setOperationAlias); var discriminatorExpression = projection1.DiscriminatorExpression; if (projection1.DiscriminatorExpression != null @@ -2803,7 +2752,7 @@ void ProcessStructuralType( var innerProjection = new ProjectionExpression(projection1.DiscriminatorExpression, alias); select1._projection.Add(innerProjection); select2._projection.Add(new ProjectionExpression(projection2.DiscriminatorExpression, alias)); - discriminatorExpression = new ConcreteColumnExpression(innerProjection, tableReferenceExpression); + discriminatorExpression = CreateColumnExpression(innerProjection, setOperationAlias); } var outerProjection = new StructuralTypeProjectionExpression( @@ -2874,13 +2823,9 @@ public void ApplyDefaultIfEmpty(ISqlExpressionFactory sqlExpressionFactory) var joinPredicate = sqlExpressionFactory.Equal(sqlExpressionFactory.Constant(1), sqlExpressionFactory.Constant(1)); var joinTable = new LeftJoinExpression(Tables.Single(), joinPredicate); - var joinTableReferenceExpression = _tableReferences.Single(); _tables.Clear(); - _tableReferences.Clear(); - AddTable(dummySelectExpression, new TableReferenceExpression(this, dummySelectExpression.Alias!)); - // Do NOT use AddTable here since we are adding the same table which was current as join table we don't need to traverse it. + _tables.Add(dummySelectExpression); _tables.Add(joinTable); - _tableReferences.Add(joinTableReferenceExpression); var projectionMapping = new Dictionary(); foreach (var projection in _projectionMapping) @@ -2949,7 +2894,8 @@ static IReadOnlyDictionary GetPropertyExpressions( ColumnExpression identifyingColumn) { var propertyExpressions = new Dictionary(); - var tableExpressionBase = UnwrapJoinExpression(identifyingColumn.Table); + var tableExpressionBase = selectExpression.GetTable(identifyingColumn).UnwrapJoin(); + var tableAlias = tableExpressionBase.GetRequiredAlias(); if (tableExpressionBase is SelectExpression subquery) { // If identifying column is from a subquery then the owner table is inside subquery @@ -2961,11 +2907,9 @@ static IReadOnlyDictionary GetPropertyExpressions( var subqueryPropertyExpressions = GetPropertyExpressions( sqlExpressionFactory, sqlAliasManager, navigation, subquery, subqueryIdentifyingColumn); var changeNullability = identifyingColumn.IsNullable && !subqueryIdentifyingColumn.IsNullable; - var tableIndex = selectExpression._tables.FindIndex(e => ReferenceEquals(e, identifyingColumn.Table)); - var subqueryTableReferenceExpression = selectExpression._tableReferences[tableIndex]; foreach (var (property, columnExpression) in subqueryPropertyExpressions) { - var outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, columnExpression); + var outerColumn = subquery.GenerateOuterColumn(tableAlias, columnExpression); if (changeNullability) { outerColumn = outerColumn.MakeNullable(); @@ -2979,7 +2923,7 @@ static IReadOnlyDictionary GetPropertyExpressions( // This is the select expression where owner table exists // where we would look for same table or generate joins - var sourceTableForAnnotations = FindRootTableExpressionForColumn(identifyingColumn.Table, identifyingColumn.Name); + var sourceTableForAnnotations = FindRootTableExpressionForColumn(selectExpression, identifyingColumn); var ownerType = navigation.DeclaringEntityType; var entityType = navigation.TargetEntityType; var principalMappings = ownerType.GetViewOrTableMappings().Select(e => e.Table); @@ -2998,12 +2942,10 @@ static IReadOnlyDictionary GetPropertyExpressions( var principalTables = principalMappings.ToList(); var dependentTables = entityType.GetViewOrTableMappings().Select(e => e.Table).ToList(); - var baseTableIndex = selectExpression._tables.FindIndex(teb => ReferenceEquals(teb, identifyingColumn.Table)); + var baseTableIndex = selectExpression._tables.FindIndex(teb => ReferenceEquals(teb.UnwrapJoin(), tableExpressionBase)); var dependentMainTable = dependentTables[0]; - var tableReferenceExpressionMap = new Dictionary(); + var tableMap = new Dictionary(); var keyProperties = entityType.FindPrimaryKey()!.Properties; - TableReferenceExpression mainTableReferenceExpression; - TableReferenceExpression tableReferenceExpression; if (tableExpressionBase is TableExpression) { // This has potential to pull data from existing table @@ -3018,20 +2960,19 @@ static IReadOnlyDictionary GetPropertyExpressions( if (derivedTpt) { baseTableIndex = selectExpression._tables.FindIndex( - teb => ((TableExpression)UnwrapJoinExpression(teb)).Table == principalTables[0]); + teb => ((TableExpression)teb.UnwrapJoin()).Table == principalTables[0]); } var tableIndex = baseTableIndex + matchingTableIndex; - mainTableReferenceExpression = selectExpression._tableReferences[tableIndex]; - tableReferenceExpressionMap[dependentMainTable] = mainTableReferenceExpression; + var mainTableAlias = selectExpression.Tables[tableIndex].GetRequiredAlias(); + tableMap[dependentMainTable] = mainTableAlias; if (dependentTables.Count > 1) { var joinColumns = new List(); foreach (var property in keyProperties) { - var columnExpression = new ConcreteColumnExpression( - property, dependentMainTable.FindColumn(property)!, mainTableReferenceExpression, - pkColumnsNullable); + var columnExpression = CreateColumnExpression( + property, dependentMainTable.FindColumn(property)!, mainTableAlias, pkColumnsNullable); propertyExpressions[property] = columnExpression; joinColumns.Add(columnExpression); } @@ -3043,7 +2984,7 @@ static IReadOnlyDictionary GetPropertyExpressions( if (matchingTableIndex != -1) { // We don't need to generate join for this - tableReferenceExpressionMap[table] = selectExpression._tableReferences[baseTableIndex + matchingTableIndex]; + tableMap[table] = selectExpression.Tables[baseTableIndex + matchingTableIndex].GetRequiredAlias(); } else { @@ -3054,17 +2995,15 @@ static IReadOnlyDictionary GetPropertyExpressions( tableExpression = tableExpression.AddAnnotation(annotation.Name, annotation.Value); } - tableReferenceExpression = new TableReferenceExpression(selectExpression, alias); - tableReferenceExpressionMap[table] = tableReferenceExpression; + tableMap[table] = alias; var innerColumns = keyProperties.Select( - p => CreateColumnExpression(p, table, tableReferenceExpression, nullable: false)); + p => CreateColumnExpression(p, table, alias, nullable: false)); var joinPredicate = joinColumns .Zip(innerColumns, sqlExpressionFactory.Equal) .Aggregate(sqlExpressionFactory.AndAlso); - var joinExpression = new LeftJoinExpression(tableExpression, joinPredicate, prunable: true); - selectExpression.AddTable(joinExpression, tableReferenceExpression); + selectExpression._tables.Add(new LeftJoinExpression(tableExpression, joinPredicate, prunable: true)); } } } @@ -3081,7 +3020,7 @@ static IReadOnlyDictionary GetPropertyExpressions( ? dependentMainTable.FindColumn(property)! : dependentTables.Select(e => e.FindColumn(property)).First(e => e != null)!; propertyExpressions[property] = CreateColumnExpression( - property, columnBase, tableReferenceExpressionMap[columnBase.Table], + property, columnBase, tableMap[columnBase.Table], nullable: property.IsPrimaryKey() ? pkColumnsNullable : newColumnsNullable); } @@ -3092,12 +3031,10 @@ static IReadOnlyDictionary GetPropertyExpressions( // Either we encountered a custom table source or dependent is not sharing table // In either case we need to generate join to owner var ownerJoinColumns = new List(); - var ownerTableReferenceExpression = selectExpression._tableReferences[baseTableIndex]; foreach (var property in navigation.ForeignKey.PrincipalKey.Properties) { var columnBase = principalTables.Select(e => e.FindColumn(property)).First(e => e != null)!; - var columnExpression = new ConcreteColumnExpression( - property, columnBase, ownerTableReferenceExpression, pkColumnsNullable); + var columnExpression = CreateColumnExpression(property, columnBase, tableAlias, pkColumnsNullable); ownerJoinColumns.Add(columnExpression); } @@ -3108,23 +3045,21 @@ static IReadOnlyDictionary GetPropertyExpressions( ownedTable = ownedTable.AddAnnotation(annotation.Name, annotation.Value); } - mainTableReferenceExpression = new TableReferenceExpression(selectExpression, ownedTableAlias); var outerJoinPredicate = ownerJoinColumns .Zip( navigation.ForeignKey.Properties - .Select(p => CreateColumnExpression(p, dependentMainTable, mainTableReferenceExpression, nullable: false))) + .Select(p => CreateColumnExpression(p, dependentMainTable, ownedTableAlias, nullable: false))) .Select(i => sqlExpressionFactory.Equal(i.First, i.Second)) .Aggregate(sqlExpressionFactory.AndAlso); - var joinedTable = new LeftJoinExpression(ownedTable, outerJoinPredicate); - tableReferenceExpressionMap[dependentMainTable] = mainTableReferenceExpression; - selectExpression.AddTable(joinedTable, mainTableReferenceExpression); + selectExpression._tables.Add(new LeftJoinExpression(ownedTable, outerJoinPredicate)); + tableMap[dependentMainTable] = ownedTableAlias; if (dependentTables.Count > 1) { var joinColumns = new List(); foreach (var property in keyProperties) { - var columnExpression = new ConcreteColumnExpression( - property, dependentMainTable.FindColumn(property)!, mainTableReferenceExpression, newColumnsNullable); + var columnExpression = CreateColumnExpression( + property, dependentMainTable.FindColumn(property)!, ownedTableAlias, newColumnsNullable); propertyExpressions[property] = columnExpression; joinColumns.Add(columnExpression); } @@ -3139,17 +3074,15 @@ static IReadOnlyDictionary GetPropertyExpressions( tableExpression = tableExpression.AddAnnotation(annotation.Name, annotation.Value); } - tableReferenceExpression = new TableReferenceExpression(selectExpression, alias); - tableReferenceExpressionMap[table] = tableReferenceExpression; + tableMap[table] = alias; var innerColumns = keyProperties.Select( - p => CreateColumnExpression(p, table, tableReferenceExpression, nullable: false)); + p => CreateColumnExpression(p, table, alias, nullable: false)); var joinPredicate = joinColumns .Zip(innerColumns, sqlExpressionFactory.Equal) .Aggregate(sqlExpressionFactory.AndAlso); - var joinExpression = new LeftJoinExpression(tableExpression, joinPredicate, prunable: true); - selectExpression.AddTable(joinExpression, tableReferenceExpression); + selectExpression._tables.Add(new LeftJoinExpression(tableExpression, joinPredicate, prunable: true)); } } @@ -3165,7 +3098,7 @@ static IReadOnlyDictionary GetPropertyExpressions( ? dependentMainTable.FindColumn(property)! : dependentTables.Select(e => e.FindColumn(property)).First(e => e != null)!; propertyExpressions[property] = CreateColumnExpression( - property, columnBase, tableReferenceExpressionMap[columnBase.Table], + property, columnBase, tableMap[columnBase.Table], nullable: newColumnsNullable); } @@ -3177,22 +3110,20 @@ static IReadOnlyDictionary GetPropertyExpressions( return propertyExpressions; } - static TableExpressionBase FindRootTableExpressionForColumn(TableExpressionBase table, string columnName) + static TableExpressionBase FindRootTableExpressionForColumn(SelectExpression select, ColumnExpression column) { - if (table is JoinExpressionBase joinExpressionBase) - { - table = joinExpressionBase.Table; - } - else if (table is SetOperationBase setOperationBase) + var table = select.GetTable(column).UnwrapJoin(); + + if (table is SetOperationBase setOperationBase) { table = setOperationBase.Source1; } - if (table is SelectExpression selectExpression) + if (table is SelectExpression innerSelect) { - var matchingProjection = (ColumnExpression)selectExpression.Projection.Single(p => p.Alias == columnName).Expression; + var matchingProjection = (ColumnExpression)innerSelect.Projection.Single(p => p.Alias == column.Name).Expression; - return FindRootTableExpressionForColumn(matchingProjection.Table, matchingProjection.Name); + return FindRootTableExpressionForColumn(innerSelect, matchingProjection); } return table; @@ -3239,7 +3170,7 @@ public static StructuralTypeShaperExpression GenerateComplexPropertyShaperExpres // If the source is itself a complex type (nested complex type), its table map is already suitable and we can just pass it on. var newTableMap = containerProjection.TableMap.Count == 1 ? containerProjection.TableMap - : new Dictionary { [complexTypeTable] = tableReferenceExpression }; + : new Dictionary { [complexTypeTable] = tableReferenceExpression }; Check.DebugAssert(newTableMap.Single().Key == complexTypeTable, "Bad new table map"); @@ -3251,6 +3182,37 @@ public static StructuralTypeShaperExpression GenerateComplexPropertyShaperExpres return entityShaper; } + /// + /// Retrieves the referenced by the given column, looking it up on this + /// based on its alias. + /// + public TableExpressionBase GetTable(ColumnExpression column) + { + foreach (var table in Tables) + { + if (table.UnwrapJoin().Alias == column.TableAlias) + { + return table; + } + } + + throw new InvalidOperationException($"Table not found with alias '{column.TableAlias}'"); + } + + private bool ContainsReferencedTable(ColumnExpression column) + { + foreach (var table in Tables) + { + var unwrappedTable = table.UnwrapJoin(); + if (unwrappedTable.Alias == column.TableAlias) + { + return true; + } + } + + return false; + } + private enum JoinType { InnerJoin, @@ -3414,9 +3376,8 @@ private void AddJoin( joinPredicate = innerSelectExpression.PushdownIntoSubqueryInternal().Remap(joinPredicate); - var subqueryTableReference = innerSelectExpression._tableReferences.Single(); var outerColumn = ((SelectExpression)innerSelectExpression.Tables[0]).GenerateOuterColumn( - subqueryTableReference, rowNumberExpression, "row"); + innerSelectExpression.Tables[0].Alias!, rowNumberExpression, "row"); SqlExpression? offsetPredicate = null; SqlExpression? limitPredicate = null; if (offset != null) @@ -3545,9 +3506,7 @@ private void AddJoin( _ => throw new InvalidOperationException(CoreStrings.InvalidSwitch(nameof(joinType), joinType)) }; - var tableReferenceExpression = innerSelectExpression._tableReferences[0]; - tableReferenceExpression.UpdateTableReference(innerSelectExpression, this); - AddTable(joinTable, tableReferenceExpression); + _tables.Add(joinTable); static void GetPartitions(SelectExpression selectExpression, SqlExpression sqlExpression, List partitions) { @@ -3556,7 +3515,7 @@ static void GetPartitions(SelectExpression selectExpression, SqlExpression sqlEx if (sqlBinaryExpression.OperatorType == ExpressionType.Equal) { if (sqlBinaryExpression.Left is ColumnExpression columnExpression - && selectExpression.ContainsTableReference(columnExpression)) + && selectExpression.ContainsReferencedTable(columnExpression)) { partitions.Add(sqlBinaryExpression.Left); } @@ -3608,7 +3567,7 @@ static void GetPartitions(SelectExpression selectExpression, SqlExpression sqlEx || inner.GroupBy.Count > 0)) { var innerKeyColumns = new List(); - PopulateInnerKeyColumns(inner.Tables, joinPredicate, innerKeyColumns); + PopulateInnerKeyColumns(inner, joinPredicate, innerKeyColumns); // if projection has already been applied we can use it directly // otherwise we extract future projection columns from projection mapping @@ -3747,7 +3706,7 @@ or ExpressionType.LessThan static bool IsContainedSql(SelectExpression selectExpression, SqlExpression sqlExpression) => sqlExpression switch { - ColumnExpression columnExpression => selectExpression.ContainsTableReference(columnExpression), + ColumnExpression columnExpression => selectExpression.ContainsReferencedTable(columnExpression), // We check condition in a separate function to avoid matching structure of condition outside of case block CaseExpression @@ -3756,7 +3715,7 @@ static bool IsContainedSql(SelectExpression selectExpression, SqlExpression sqlE WhenClauses: [{ Result: ColumnExpression resultColumn } whenClause], ElseResult: null } - => IsContainedCondition(selectExpression, whenClause.Test) && selectExpression.ContainsTableReference(resultColumn), + => IsContainedCondition(selectExpression, whenClause.Test) && selectExpression.ContainsReferencedTable(resultColumn), _ => false }; @@ -3775,7 +3734,7 @@ static bool IsContainedCondition(SelectExpression selectExpression, SqlExpressio { // We don't check left/right inverted because we generate this. return sqlBinaryExpression is { Left: ColumnExpression column, Right: SqlConstantExpression { Value: null } } - && selectExpression.ContainsTableReference(column); + && selectExpression.ContainsReferencedTable(column); } return IsContainedCondition(selectExpression, sqlBinaryExpression.Left) @@ -3783,19 +3742,19 @@ static bool IsContainedCondition(SelectExpression selectExpression, SqlExpressio } static void PopulateInnerKeyColumns( - IEnumerable tables, + SelectExpression select, SqlExpression joinPredicate, List resultColumns) { - if (joinPredicate is SqlBinaryExpression sqlBinaryExpression) - { - PopulateInnerKeyColumns(tables, sqlBinaryExpression.Left, resultColumns); - PopulateInnerKeyColumns(tables, sqlBinaryExpression.Right, resultColumns); - } - else if (joinPredicate is ColumnExpression columnExpression - && tables.Contains(columnExpression.Table)) + switch (joinPredicate) { - resultColumns.Add(columnExpression); + case SqlBinaryExpression binary: + PopulateInnerKeyColumns(select, binary.Left, resultColumns); + PopulateInnerKeyColumns(select, binary.Right, resultColumns); + break; + case ColumnExpression columnExpression when select.ContainsReferencedTable(columnExpression): + resultColumns.Add(columnExpression); + break; } } @@ -3971,8 +3930,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr { var subqueryAlias = _sqlAliasManager.GenerateTableAlias("t"); var subquery = new SelectExpression( - subqueryAlias, [], _tables.ToList(), _tableReferences.ToList(), _groupBy.ToList(), - _orderings.ToList(), GetAnnotations(), _sqlAliasManager) + subqueryAlias, [], _tables.ToList(), _groupBy.ToList(), _orderings.ToList(), GetAnnotations(), _sqlAliasManager) { IsDistinct = IsDistinct, Predicate = Predicate, @@ -3982,7 +3940,6 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr _mutable = false }; _tables.Clear(); - _tableReferences.Clear(); _groupBy.Clear(); _orderings.Clear(); IsDistinct = false; @@ -3998,16 +3955,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr _tpcDiscriminatorValues.Clear(); - var subqueryTableReferenceExpression = new TableReferenceExpression(this, subquery.Alias!); - // Do NOT use AddTable here. The subquery already have unique aliases we don't need to traverse it again to make it unique. _tables.Add(subquery); - _tableReferences.Add(subqueryTableReferenceExpression); - - // Remap tableReferences in inner so that all components follow referential integrity. - foreach (var tableReference in subquery._tableReferences) - { - tableReference.UpdateTableReference(this, subquery); - } var projectionMap = new Dictionary(ReferenceEqualityComparer.Instance); @@ -4017,7 +3965,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr _projection.Clear(); foreach (var projection in projections) { - var outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, projection.Expression, projection.Alias); + var outerColumn = subquery.GenerateOuterColumn(subqueryAlias, projection.Expression, projection.Alias); AddToProjection(outerColumn, null); projectionMap[projection.Expression] = outerColumn; } @@ -4038,7 +3986,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr if (item is StructuralTypeProjectionExpression projection) { - _clientProjections[i] = LiftEntityProjectionFromSubquery(projection, subqueryTableReferenceExpression); + _clientProjections[i] = LiftEntityProjectionFromSubquery(projection, subqueryAlias); } else if (item is JsonQueryExpression jsonQueryExpression) { @@ -4047,7 +3995,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr else if (item is SqlExpression sqlExpression) { var alias = _aliasForClientProjections[i]; - var outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, sqlExpression, alias); + var outerColumn = subquery.GenerateOuterColumn(subqueryAlias, sqlExpression, alias); projectionMap[sqlExpression] = outerColumn; _clientProjections[i] = outerColumn; _aliasForClientProjections[i] = null; @@ -4070,7 +4018,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr if (expression is StructuralTypeProjectionExpression projection) { - _projectionMapping[projectionMember] = LiftEntityProjectionFromSubquery(projection, subqueryTableReferenceExpression); + _projectionMapping[projectionMember] = LiftEntityProjectionFromSubquery(projection, subqueryAlias); } else if (expression is JsonQueryExpression jsonQueryExpression) { @@ -4080,7 +4028,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr { var innerColumn = (SqlExpression)expression; var outerColumn = subquery.GenerateOuterColumn( - subqueryTableReferenceExpression, innerColumn, projectionMember.Last?.Name); + subqueryAlias, innerColumn, projectionMember.Last?.Name); projectionMap[innerColumn] = outerColumn; _projectionMapping[projectionMember] = outerColumn; } @@ -4092,7 +4040,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr { foreach (var key in subquery._groupBy) { - projectionMap[key] = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, key); + projectionMap[key] = subquery.GenerateOuterColumn(subqueryAlias, key); } } @@ -4103,7 +4051,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr // Invariant, identifier should not contain term which cannot be projected out. if (!projectionMap.TryGetValue(column, out var outerColumn)) { - outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, column); + outerColumn = subquery.GenerateOuterColumn(subqueryAlias, column); } _identifier.Add((outerColumn, Comparer: comparer)); @@ -4116,7 +4064,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr // Invariant, identifier should not contain term which cannot be projected out. if (!projectionMap.TryGetValue(column, out var outerColumn)) { - outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, column); + outerColumn = subquery.GenerateOuterColumn(subqueryAlias, column); } _childIdentifiers.Add((outerColumn, Comparer: comparer)); @@ -4136,7 +4084,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr { _orderings.Add( ordering.Update( - subquery.GenerateOuterColumn(subqueryTableReferenceExpression, orderingExpression))); + subquery.GenerateOuterColumn(subqueryAlias, orderingExpression))); } else { @@ -4151,15 +4099,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr subquery.ClearOrdering(); } - // Remap tableReferences in inner - foreach (var tableReference in subquery._tableReferences) - { - tableReference.UpdateTableReference(this, subquery); - } - - var tableReferenceUpdatingExpressionVisitor = new TableReferenceUpdatingExpressionVisitor(this, subquery); - var sqlRemappingVisitor = new SqlRemappingVisitor(projectionMap, subquery, subqueryTableReferenceExpression); - tableReferenceUpdatingExpressionVisitor.Visit(subquery); + var sqlRemappingVisitor = new SqlRemappingVisitor(projectionMap, subquery, subqueryAlias); if (nestedQueryInProjection) { @@ -4177,7 +4117,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr StructuralTypeProjectionExpression LiftEntityProjectionFromSubquery( StructuralTypeProjectionExpression projection, - TableReferenceExpression subqueryTableReference) + string subqueryAlias) { var propertyExpressions = new Dictionary(); @@ -4197,7 +4137,7 @@ void HandleTypeProjection(StructuralTypeProjectionExpression typeProjection) } var innerColumn = typeProjection.BindProperty(property); - var outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, innerColumn); + var outerColumn = subquery.GenerateOuterColumn(subqueryAlias, innerColumn); projectionMap[innerColumn] = outerColumn; propertyExpressions[property] = outerColumn; } @@ -4213,11 +4153,11 @@ void HandleTypeProjection(StructuralTypeProjectionExpression typeProjection) if (projection.DiscriminatorExpression != null) { discriminatorExpression = subquery.GenerateOuterColumn( - subqueryTableReferenceExpression, projection.DiscriminatorExpression, DiscriminatorColumnAlias); + subqueryAlias, projection.DiscriminatorExpression, DiscriminatorColumnAlias); projectionMap[projection.DiscriminatorExpression] = discriminatorExpression; } - var tableMap = projection.TableMap.ToDictionary(kvp => kvp.Key, _ => subqueryTableReference); + var tableMap = projection.TableMap.ToDictionary(kvp => kvp.Key, _ => subqueryAlias); var newEntityProjection = new StructuralTypeProjectionExpression( projection.StructuralType, propertyExpressions, tableMap, nullable: false, discriminatorExpression); @@ -4234,7 +4174,7 @@ void HandleTypeProjection(StructuralTypeProjectionExpression typeProjection) { var newValueBufferExpression = boundEntityShaperExpression.ValueBufferExpression is StructuralTypeProjectionExpression innerEntityProjection - ? (Expression)LiftEntityProjectionFromSubquery(innerEntityProjection, subqueryTableReferenceExpression) + ? (Expression)LiftEntityProjectionFromSubquery(innerEntityProjection, subqueryAlias) : LiftJsonQueryFromSubquery((JsonQueryExpression)boundEntityShaperExpression.ValueBufferExpression); boundEntityShaperExpression = boundEntityShaperExpression.Update(newValueBufferExpression); @@ -4255,7 +4195,7 @@ JsonQueryExpression LiftJsonQueryFromSubquery(JsonQueryExpression jsonQueryExpre jsonQueryExpression.JsonColumn.TypeMapping, jsonQueryExpression.IsNullable); - var newJsonColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, jsonScalarExpression); + var newJsonColumn = subquery.GenerateOuterColumn(subqueryAlias, jsonScalarExpression); var newKeyPropertyMap = new Dictionary(); var keyProperties = jsonQueryExpression.KeyPropertyMap.Keys.ToList(); @@ -4263,7 +4203,7 @@ JsonQueryExpression LiftJsonQueryFromSubquery(JsonQueryExpression jsonQueryExpre { var keyProperty = keyProperties[i]; var innerColumn = jsonQueryExpression.BindProperty(keyProperty); - var outerColumn = subquery.GenerateOuterColumn(subqueryTableReferenceExpression, innerColumn); + var outerColumn = subquery.GenerateOuterColumn(subqueryAlias, innerColumn); projectionMap[innerColumn] = outerColumn; newKeyPropertyMap[keyProperty] = outerColumn; } @@ -4325,17 +4265,12 @@ public ColumnExpression CreateColumnExpression( Type type, RelationalTypeMapping? typeMapping, bool? columnNullable = null) - { - var tableIndex = _tables.FindIndex(teb => ReferenceEquals(teb, tableExpression)); - var tableReferenceExpression = _tableReferences[tableIndex]; - - return new ConcreteColumnExpression( + => new( columnName, - tableReferenceExpression, + tableExpression.GetRequiredAlias(), type.UnwrapNullableType(), typeMapping, columnNullable ?? type.IsNullableType()); - } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4354,6 +4289,11 @@ public SelectExpression Clone() /// public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloningExpressionVisitor) { + var newTables = _tables.Select(cloningExpressionVisitor.Visit).ToList(); + var tpcTablesMap = _tables.Select(TableExpressionExtensions.UnwrapJoin).Zip(newTables.Select(TableExpressionExtensions.UnwrapJoin)) + .Where(e => e.First is TpcTablesExpression) + .ToDictionary(e => (TpcTablesExpression)e.First, e => (TpcTablesExpression)e.Second); + var newProjectionMappings = new Dictionary(_projectionMapping.Count); foreach (var (projectionMember, value) in _projectionMapping) { @@ -4362,16 +4302,6 @@ public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloni var newProjections = _projection.Select(cloningExpressionVisitor.Visit).ToList(); - var newTables = _tables.Select(cloningExpressionVisitor.Visit).ToList(); - var tpcTablesMap = _tables.Select(UnwrapJoinExpression).Zip(newTables.Select(UnwrapJoinExpression)) - .Where(e => e.First is TpcTablesExpression) - .ToDictionary(e => (TpcTablesExpression)e.First, e => (TpcTablesExpression)e.Second); - - // 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 = newTables.Select(t => new TableReferenceExpression(this, t.UnwrapJoin().Alias!)).ToList(); - var predicate = (SqlExpression?)cloningExpressionVisitor.Visit(Predicate); var newGroupBy = _groupBy.Select(cloningExpressionVisitor.Visit) .Where(e => e is not (SqlConstantExpression or SqlParameterExpression)) @@ -4382,7 +4312,7 @@ public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloni var limit = (SqlExpression?)cloningExpressionVisitor.Visit(Limit); var newSelectExpression = new SelectExpression( - alias, newProjections, newTables, newTableReferences, newGroupBy, newOrderings, GetAnnotations(), _sqlAliasManager) + alias, newProjections, newTables, newGroupBy, newOrderings, GetAnnotations(), _sqlAliasManager) { Predicate = predicate, Having = havingExpression, @@ -4394,28 +4324,22 @@ public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloni _mutable = _mutable }; - foreach (var kvp in _tpcDiscriminatorValues) + // The below contain ColumnExpressions which need to be recreated if a table's alias is modified during cloning + foreach (var (tpcTablesExpression, (column, discriminatorValues)) in _tpcDiscriminatorValues) { - newSelectExpression._tpcDiscriminatorValues[tpcTablesMap[kvp.Key]] = kvp.Value; + newSelectExpression._tpcDiscriminatorValues[tpcTablesMap[tpcTablesExpression]] = + ((ColumnExpression)cloningExpressionVisitor.Visit(column), discriminatorValues); } - // Since identifiers are ColumnExpression, they are not visited since they don't contain SelectExpression inside it. - newSelectExpression._identifier.AddRange(_identifier); - newSelectExpression._childIdentifiers.AddRange(_childIdentifiers); - - // Remap tableReferences in new select expression - foreach (var tableReference in newTableReferences) + foreach (var (column, comparer) in _identifier) { - tableReference.UpdateTableReference(this, newSelectExpression); + newSelectExpression._identifier.Add(((ColumnExpression)cloningExpressionVisitor.Visit(column), comparer)); } - Check.DebugAssert( - newTables.Select(GetAliasFromTableExpressionBase).SequenceEqual(newTableReferences.Select(e => e.Alias)), - "Alias of updated tables must match the old tables."); - - // Now that we have SelectExpression, we visit all components and update table references inside columns - newSelectExpression = (SelectExpression)new ColumnExpressionReplacingExpressionVisitor( - this, newSelectExpression._tableReferences).Visit(newSelectExpression); + foreach (var (column, comparer) in _childIdentifiers) + { + newSelectExpression._childIdentifiers.Add(((ColumnExpression)cloningExpressionVisitor.Visit(column), comparer)); + } return newSelectExpression; } @@ -4449,12 +4373,12 @@ public void Prune(SqlTreePruner pruningVisitor, bool pruneProjection) var referencedColumnMap = pruningVisitor.ReferencedColumnMap; // Prune the projection; any projected alias that isn't referenced on us from the outside can be removed. We avoid doing that when: // 1. The caller requests we don't (top-level select, scalar subquery, select within a set operation where the other is distinct - - // projection must be preserved as-is) + // projection must be preserved as-is) // 2. The select has distinct (removing a projection changes which rows get projected out) var prunedProjection = _projection; - if (pruneProjection && !IsDistinct) + if (pruneProjection && !IsDistinct && ((Alias ?? pruningVisitor.CurrentTableAlias) is string currentTableAlias)) { - if (referencedColumnMap.TryGetValue(this, out var referencedProjectionAliases)) + if (referencedColumnMap.TryGetValue(currentTableAlias, out var referencedProjectionAliases)) { for (var i = _projection.Count - 1; i >= 0; i--) { @@ -4470,6 +4394,11 @@ public void Prune(SqlTreePruner pruningVisitor, bool pruneProjection) } } + // When visiting the select's tables, we track the alias so that we know it when processing nested table expressions (e.g. within + // set operations); make sure that when visiting other clauses (e.g. predicate), the tracked table alias is null. + var parentTableAlias = pruningVisitor.CurrentTableAlias; + pruningVisitor.CurrentTableAlias = null; + // First visit all the non-table clauses of the SelectExpression - this will populate referencedColumnMap with all columns // referenced on all tables. if (pruningVisitor.VisitAndConvert(prunedProjection) is var newProjection && newProjection != _projection) @@ -4515,49 +4444,32 @@ public void Prune(SqlTreePruner pruningVisitor, bool pruneProjection) for (var i = _tables.Count - 1; i >= 0; i--) { var table = _tables[i]; - var wrappedTable = table.UnwrapJoin(); + var alias = table.GetRequiredAlias(); - if (!referencedColumnMap.ContainsKey(wrappedTable) + if (!referencedColumnMap.ContainsKey(alias) // Note that we only prune joins; pruning the main is more complex because other tables need to unwrap joins to be main. // We also only prune joins explicitly marked as prunable; otherwise e.g. an inner join may be needed to filter out rows // even if no column references it. && table is JoinExpressionBase { IsPrunable: true }) { _tables.RemoveAt(i); - _tableReferences.RemoveAt(i); continue; } // The table wasn't pruned - visit it. This may add references to a previous table, causing it to be preserved (e.g. if it's // referenced from the join predicate), or just prune something inside (e.g. a subquery table). + // Note that we track the table's alias in CurrentTableAlias, in case it contains nested selects (i.e. within set operations), + // which don't have their own alias. + pruningVisitor.CurrentTableAlias = alias; var newTable = (TableExpressionBase)pruningVisitor.Visit(table); + if (newTable != table) { _tables[i] = newTable; } } - } - /// - /// 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. - /// - [EntityFrameworkInternal] - public void ChangeTableAlias(int tableIndex, string newAlias, HashSet visitedTableReferences) - { - // TableReferenceExpression instances can (currently) be shared by multiple SelectExpression instances in the - // same tree. We don't want to the same one multiple times, so we track the ones we already visited. - // This will all go away soon as we get rid of TableReferenceExpression altogether. - var tableReference = _tableReferences[tableIndex]; - if (!visitedTableReferences.Add(tableReference)) - { - return; - } - - _tables[tableIndex].UnwrapJoin().Alias = newAlias; - tableReference.Alias = newAlias; + pruningVisitor.CurrentTableAlias = parentTableAlias; } private Dictionary ConvertProjectionMappingToClientProjections( @@ -4623,13 +4535,6 @@ private static Expression MakeNullable(Expression expression, bool nullable) } : expression; - private static string GetAliasFromTableExpressionBase(TableExpressionBase tableExpressionBase) - // We unwrap here since alias are not assigned to wrapper expressions - => UnwrapJoinExpression(tableExpressionBase).Alias!; - - private static TableExpressionBase UnwrapJoinExpression(TableExpressionBase tableExpressionBase) - => (tableExpressionBase as JoinExpressionBase)?.Table ?? tableExpressionBase; - private static IEnumerable GetAllPropertiesInHierarchy(ITypeBase structuralType) => structuralType switch { @@ -4661,57 +4566,56 @@ private static IEnumerable GetAllNavigationsInHierarchy(IEntityType => entityType.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive()) .SelectMany(t => t.GetDeclaredNavigations()); - private static ConcreteColumnExpression CreateColumnExpression( + private static ColumnExpression CreateColumnExpression( IProperty property, ITableBase table, - TableReferenceExpression tableExpression, + string tableAlias, bool nullable) - => CreateColumnExpression(property, table.FindColumn(property)!, tableExpression, nullable); + => CreateColumnExpression(property, table.FindColumn(property)!, tableAlias, nullable); - private static ConcreteColumnExpression CreateColumnExpression( + private static ColumnExpression CreateColumnExpression( IProperty property, - IColumnBase columnBase, - TableReferenceExpression tableExpression, + IColumnBase column, + string tableAlias, bool nullable) - => new(property, columnBase, tableExpression, nullable); + => new(column.Name, + tableAlias, + property.ClrType.UnwrapNullableType(), + column.PropertyMappings.First(m => m.Property == property).TypeMapping, + nullable || column.IsNullable); + + private static ColumnExpression CreateColumnExpression(ProjectionExpression subqueryProjection, string tableAlias) + => new( + subqueryProjection.Alias, + tableAlias, + subqueryProjection.Type, + subqueryProjection.Expression.TypeMapping!, + subqueryProjection.Expression switch + { + ColumnExpression columnExpression => columnExpression.IsNullable, + SqlConstantExpression sqlConstantExpression => sqlConstantExpression.Value == null, + _ => true + }); - private ConcreteColumnExpression GenerateOuterColumn( - TableReferenceExpression tableReferenceExpression, + private ColumnExpression GenerateOuterColumn( + string tableAlias, SqlExpression projection, - string? alias = null) + string? columnAlias = null) { // TODO: Add check if we can add projection in subquery to generate out column // Subquery having Distinct or GroupBy can block it. - var index = AddToProjection(projection, alias); + var index = AddToProjection(projection, columnAlias); - return new ConcreteColumnExpression(_projection[index], tableReferenceExpression); - } - - private bool ContainsTableReference(ColumnExpression column) - // This method is used when evaluating join correlations. - // At that point aliases are not uniquified across so we need to match tables - => Tables.Any(e => ReferenceEquals(e, column.Table)); - - private void AddTable(TableExpressionBase tableExpressionBase, TableReferenceExpression tableReferenceExpression) - { - Check.DebugAssert(_tables.Count == _tableReferences.Count, "All the tables should have their associated TableReferences."); - Check.DebugAssert( - string.Equals( - GetAliasFromTableExpressionBase(tableExpressionBase), tableReferenceExpression.Alias, StringComparison.Ordinal), - "Alias of table and table reference should be the same."); - - _tables.Add(tableExpressionBase); - _tableReferences.Add(tableReferenceExpression); + return CreateColumnExpression(_projection[index], tableAlias); } /// protected override Expression VisitChildren(ExpressionVisitor visitor) - => VisitChildren(visitor, updateColumns: true); - - private Expression VisitChildren(ExpressionVisitor visitor, bool updateColumns) { if (_mutable) { + VisitList(_tables, inPlace: true, out _); + // If projection is not populated then we need to treat this as mutable object since it is not final yet. if (_clientProjections.Count > 0) { @@ -4730,11 +4634,6 @@ private Expression VisitChildren(ExpressionVisitor visitor, bool updateColumns) _projectionMapping = projectionMapping; } - var newTables = VisitList(_tables, inPlace: true, out var tablesChanged); - Check.DebugAssert( - !tablesChanged - || newTables.Select(GetAliasFromTableExpressionBase).SequenceEqual(_tableReferences.Select(e => e.Alias)), - "Alias of updated tables must match the old tables."); Predicate = (SqlExpression?)visitor.Visit(Predicate); var newGroupBy = _groupBy; @@ -4796,23 +4695,21 @@ private Expression VisitChildren(ExpressionVisitor visitor, bool updateColumns) } else { + var changed = false; + + var newTables = VisitList(_tables, inPlace: false, out var tablesChanged); + changed |= tablesChanged; + // If projection is populated then // Either this SelectExpression is not bound to a shaped query expression // Or it is post-translation phase where it will update the shaped query expression // So we will treat it as immutable - var newProjections = VisitList(_projection, inPlace: false, out var changed); + var newProjections = VisitList(_projection, inPlace: false, out var projectionChanged); + changed |= projectionChanged; // We don't need to visit _clientProjection/_projectionMapping here // because once projection is populated both of them contains expressions for client binding rather than a server query. - var newTables = VisitList(_tables, inPlace: false, out var tablesChanged); - changed |= tablesChanged; - - Check.DebugAssert( - !tablesChanged - || newTables.Select(GetAliasFromTableExpressionBase).SequenceEqual(_tableReferences.Select(e => e.Alias)), - "Alias of updated tables must match the old tables."); - var predicate = (SqlExpression?)visitor.Visit(Predicate); changed |= predicate != Predicate; @@ -4872,9 +4769,8 @@ private Expression VisitChildren(ExpressionVisitor visitor, bool updateColumns) if (changed) { - var newTableReferences = _tableReferences.ToList(); var newSelectExpression = new SelectExpression( - Alias, newProjections, newTables, newTableReferences, newGroupBy, newOrderings, GetAnnotations(), _sqlAliasManager) + Alias, newProjections, newTables, newGroupBy, newOrderings, GetAnnotations(), _sqlAliasManager) { _clientProjections = _clientProjections, _projectionMapping = _projectionMapping, @@ -4895,39 +4791,6 @@ private Expression VisitChildren(ExpressionVisitor visitor, bool updateColumns) newSelectExpression._childIdentifiers.AddRange( childIdentifier.Zip(_childIdentifiers).Select(e => (e.First, e.Second.Comparer))); - // We duplicated the SelectExpression, and must therefore also update all table reference expressions to point to it. - // If any tables have changed, we must duplicate the TableReferenceExpressions and replace all ColumnExpressions to use - // them; otherwise we end up two SelectExpressions sharing the same TableReferenceExpression instance, and if that's later - // mutated, both SelectExpressions are affected (this happened in AliasUniquifier, see #32234). - - // Otherwise, if no tables have changed, we mutate the TableReferenceExpressions (this was the previous code, left it for - // a more low-risk fix). Note that updateColumns is false only if we're already being called from - // ColumnTableReferenceUpdater to replace the ColumnExpressions, in which case we avoid infinite recursion. - if (tablesChanged && updateColumns) - { - for (var i = 0; i < newTableReferences.Count; i++) - { - newTableReferences[i] = new TableReferenceExpression(newSelectExpression, _tableReferences[i].Alias); - } - - var columnTableReferenceUpdater = new ColumnTableReferenceUpdater(this, newSelectExpression); - newSelectExpression = (SelectExpression)columnTableReferenceUpdater.Visit(newSelectExpression); - } - else - { - // Remap tableReferences in new select expression - foreach (var tableReference in newTableReferences) - { - tableReference.UpdateTableReference(this, newSelectExpression); - } - - // TODO: Why does need to be done? We've already updated all table references on the new select just above, and - // no ColumnExpression in the query is every supposed to reference a TableReferenceExpression that isn't in the - // select's list... The same thing is done in all other places where TableReferenceUpdatingExpressionVisitor is used. - var tableReferenceUpdatingExpressionVisitor = new TableReferenceUpdatingExpressionVisitor(this, newSelectExpression); - tableReferenceUpdatingExpressionVisitor.Visit(newSelectExpression); - } - return newSelectExpression; } @@ -5011,10 +4874,8 @@ public SelectExpression Update( // TODO: This assumes that no tables were added or removed (e.g. pruning). Update should be usable for that case. // TODO: This always creates a new expression. It should check if anything changed instead (#31276), allowing us to remove "changed" // tracking from calling code. - var newTableReferences = _tableReferences.ToList(); var newSelectExpression = new SelectExpression( - Alias, projections.ToList(), tables.ToList(), newTableReferences, groupBy.ToList(), orderings.ToList(), GetAnnotations(), - _sqlAliasManager) + Alias, projections.ToList(), tables.ToList(), groupBy.ToList(), orderings.ToList(), GetAnnotations(), _sqlAliasManager) { _projectionMapping = projectionMapping, _clientProjections = _clientProjections.ToList(), @@ -5030,15 +4891,6 @@ public SelectExpression Update( // We don't copy identifiers because when we are doing reconstruction so projection is already applied. // Update method should not be used pre-projection application. There are other methods to change SelectExpression. - // Remap tableReferences in new select expression - foreach (var tableReference in newTableReferences) - { - tableReference.UpdateTableReference(this, newSelectExpression); - } - - var tableReferenceUpdatingExpressionVisitor = new TableReferenceUpdatingExpressionVisitor(this, newSelectExpression); - tableReferenceUpdatingExpressionVisitor.Visit(newSelectExpression); - return newSelectExpression; } diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs index 19a4690521e..a977be6605a 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpressionBase.cs @@ -149,4 +149,14 @@ public virtual TableExpressionBase AddAnnotation(string name, object? value) /// public virtual IEnumerable GetAnnotations() => _annotations?.Values ?? Enumerable.Empty(); + + /// + /// 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. + /// + [EntityFrameworkInternal] + public virtual string GetRequiredAlias() + => Alias ?? throw new InvalidOperationException($"No alias is defined on table: {ExpressionPrinter.Print(this)}"); } diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 37c470860b5..f3330521147 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -2016,7 +2016,7 @@ protected virtual bool TryMakeNonNullable( // We exclude the predicate since it may actually filter out nulls Projection: [{ Expression: ColumnExpression projectedColumn }] projection } - && projectedColumn.Table == collectionTable + && projectedColumn.TableAlias == collectionTable.Alias && IsCollectionTable(collectionTable, out var collection) && collection is SqlParameterExpression collectionParameter && ParameterValues[collectionParameter.Name] is IList values) diff --git a/src/EFCore.Relational/Query/SqlTreePruner.cs b/src/EFCore.Relational/Query/SqlTreePruner.cs index 4151c2abb6a..0b0d4810bcd 100644 --- a/src/EFCore.Relational/Query/SqlTreePruner.cs +++ b/src/EFCore.Relational/Query/SqlTreePruner.cs @@ -16,13 +16,29 @@ namespace Microsoft.EntityFrameworkCore.Query; /// public class SqlTreePruner : ExpressionVisitor { - private readonly Dictionary> _referencedColumnMap = new(ReferenceEqualityComparer.Instance); + private readonly Dictionary> _referencedColumnMap = new(ReferenceEqualityComparer.Instance); /// - /// Maps tables to the list of column aliases found referenced on them. + /// Maps table aliases to the list of column aliases found referenced on them. /// + // TODO: Make this protected after SelectExpression.Prune is moved into this visitor [EntityFrameworkInternal] - public virtual IReadOnlyDictionary> ReferencedColumnMap => _referencedColumnMap; + public virtual IReadOnlyDictionary> ReferencedColumnMap => _referencedColumnMap; + + /// + /// When visiting a nested (e.g. a select within a set operation), this holds the table alias + /// of the top-most table (the one which has the alias referenced by columns). This is needed in order to properly prune the + /// projection of such nested selects, which don't themselves have an alias. + /// + /// + /// 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. + /// + // TODO: Make this protected after SelectExpression.Prune is moved into this visitor + [EntityFrameworkInternal] + public virtual string? CurrentTableAlias { get; set; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -31,11 +47,7 @@ public class SqlTreePruner : ExpressionVisitor /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual Expression Prune(Expression expression) - { - _referencedColumnMap.Clear(); - - return Visit(expression); - } + => Visit(expression); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -48,11 +60,13 @@ protected override Expression VisitExtension(Expression node) switch (node) { case ShapedQueryExpression shapedQueryExpression: + _referencedColumnMap.Clear(); return shapedQueryExpression.Update( ((SelectExpression)shapedQueryExpression.QueryExpression).PruneToplevel(this), Visit(shapedQueryExpression.ShaperExpression)); case RelationalSplitCollectionShaperExpression relationalSplitCollectionShaperExpression: + _referencedColumnMap.Clear(); return relationalSplitCollectionShaperExpression.Update( relationalSplitCollectionShaperExpression.ParentIdentifier, relationalSplitCollectionShaperExpression.ChildIdentifier, @@ -75,7 +89,7 @@ protected override Expression VisitExtension(Expression node) // For any column we encounter, register it in the referenced column map, which records the aliases referenced on each table. case ColumnExpression column: - RegisterTable(column.Table.UnwrapJoin(), column); + RegisterTable(column.TableAlias, column); return column; @@ -121,18 +135,7 @@ protected override Expression VisitExtension(Expression node) return base.VisitExtension(node); } - void RegisterTable(TableExpressionBase table, ColumnExpression column) - { - _referencedColumnMap.GetOrAddNew(table).Add(column.Name); - - // If the table is a set operation, we need to recurse and register the contained tables as well. - // This is because when we visit a select inside a set operation, we need to be able to know who's referencing our - // projection from the outside (in order to prune unreferenced projections). - if (table is SetOperationBase setOperation) - { - RegisterTable(setOperation.Source1, column); - RegisterTable(setOperation.Source2, column); - } - } + void RegisterTable(string tableAlias, ColumnExpression column) + => _referencedColumnMap.GetOrAddNew(tableAlias).Add(column.Name); } } diff --git a/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs b/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs index 508054eb89f..de6b484dfa5 100644 --- a/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs +++ b/src/EFCore.Relational/Query/StructuralTypeProjectionExpression.cs @@ -31,7 +31,7 @@ public class StructuralTypeProjectionExpression : Expression public StructuralTypeProjectionExpression( ITypeBase type, IReadOnlyDictionary propertyExpressionMap, - IReadOnlyDictionary tableMap, + IReadOnlyDictionary tableMap, bool nullable = false, SqlExpression? discriminatorExpression = null) : this( @@ -48,7 +48,7 @@ private StructuralTypeProjectionExpression( ITypeBase type, IReadOnlyDictionary propertyExpressionMap, Dictionary ownedNavigationMap, - IReadOnlyDictionary tableMap, + IReadOnlyDictionary tableMap, bool nullable, SqlExpression? discriminatorExpression = null) { @@ -72,7 +72,7 @@ private StructuralTypeProjectionExpression( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public virtual IReadOnlyDictionary TableMap { get; } + public virtual IReadOnlyDictionary TableMap { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -124,14 +124,6 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) propertyExpressionMap[property] = newExpression; } - // We only need to visit the table map since TableReferenceUpdatingExpressionVisitor may need to modify it; it mutates - // TableReferenceExpression (a new TableReferenceExpression is never returned), so we never need a new table map. - foreach (var (_, tableExpression) in TableMap) - { - var newTableExpression = (TableReferenceExpression)visitor.Visit(tableExpression); - Check.DebugAssert(newTableExpression == tableExpression, $"New {nameof(TableReferenceExpression)} returned during visitation!"); - } - var discriminatorExpression = (SqlExpression?)visitor.Visit(DiscriminatorExpression); changed |= discriminatorExpression != DiscriminatorExpression; @@ -232,7 +224,7 @@ public virtual StructuralTypeProjectionExpression UpdateEntityType(IEntityType d } // Remove tables from the table map which aren't mapped to the new derived type. - Dictionary? newTableMap = null; + Dictionary? newTableMap = null; switch (entityType.GetMappingStrategy()) { case RelationalAnnotationNames.TphMappingStrategy: @@ -241,7 +233,7 @@ public virtual StructuralTypeProjectionExpression UpdateEntityType(IEntityType d case RelationalAnnotationNames.TpcMappingStrategy: case RelationalAnnotationNames.TptMappingStrategy: - newTableMap = new Dictionary(); + newTableMap = new Dictionary(); foreach (var (table, tableReferenceExpression) in TableMap) { if (table.EntityTypeMappings.Any(m => m.TypeBase == derivedType)) diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs index 1af2e93282d..512a48ad5aa 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerJsonPostprocessor.cs @@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.EntityFrameworkCore.SqlServer.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; +using ColumnInfo = Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerOpenJsonExpression.ColumnInfo; namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; @@ -26,9 +27,7 @@ public class SqlServerJsonPostprocessor : ExpressionVisitor private readonly IRelationalTypeMappingSource _typeMappingSource; private readonly ISqlExpressionFactory _sqlExpressionFactory; - private readonly - Dictionary<(SqlServerOpenJsonExpression, string), (SelectExpression SelectExpression, SqlServerOpenJsonExpression.ColumnInfo - ColumnInfo)> _columnsToRewrite = new(); + private readonly Dictionary<(string, string), ColumnInfo> _columnsToRewrite = new(); private RelationalTypeMapping? _nvarcharMaxTypeMapping; @@ -75,21 +74,21 @@ public virtual Expression Process(Expression expression) case SelectExpression selectExpression: { TableExpressionBase[]? newTables = null; - Dictionary<(SqlServerOpenJsonExpression, string), SqlServerOpenJsonExpression.ColumnInfo>? columnsToRewrite = null; + Dictionary<(string, string), ColumnInfo>? columnsToRewrite = null; for (var i = 0; i < selectExpression.Tables.Count; i++) { var table = selectExpression.Tables[i]; - if (table.UnwrapJoin() is SqlServerOpenJsonExpression { ColumnInfos: not null } openJsonExpression - && ( - // Condition 1: an ordering still refers to the OPENJSON's [key] column - ordering needs to be preserved. - selectExpression.Orderings.Select(o => o.Expression) - .Concat(selectExpression.Projection.Select(p => p.Expression)) - .Any(x => IsKeyColumn(x, table)) - || - // Condition 2: a column type in the WITH clause is a SQL Server "CLR type" (e.g. hierarchy id). - openJsonExpression.ColumnInfos.Any(c => c.TypeMapping.StoreType is "hierarchyid"))) + if (table.UnwrapJoin() is SqlServerOpenJsonExpression { ColumnInfos: { } columnInfos } openJsonExpression + // Condition 1: an ordering/projection still refers to the OPENJSON's [key] column - it needs to be preserved. + && (selectExpression.Orderings.Select(o => o.Expression) + .Concat(selectExpression.Projection.Select(p => p.Expression)) + .Any(x => IsKeyColumn(x, openJsonExpression.Alias)) + || + // Condition 2: a column type in the WITH clause is a SQL Server "CLR type" (e.g. hierarchy id). + // These are not supported by OPENJSON with WITH. + columnInfos.Any(c => c.TypeMapping.StoreType is "hierarchyid"))) { // Remove the WITH clause from the OPENJSON expression var newOpenJsonExpression = openJsonExpression.Update( @@ -104,11 +103,10 @@ public virtual Expression Process(Expression expression) _ => throw new UnreachableException() }; - foreach (var columnInfo in openJsonExpression.ColumnInfos!) + foreach (var columnInfo in columnInfos) { - columnsToRewrite ??= - new Dictionary<(SqlServerOpenJsonExpression, string), SqlServerOpenJsonExpression.ColumnInfo>(); - columnsToRewrite.Add((newOpenJsonExpression, columnInfo.Name), columnInfo); + columnsToRewrite ??= new(); + columnsToRewrite.Add((newOpenJsonExpression.Alias, columnInfo.Name), columnInfo); } if (newTables is null) @@ -150,7 +148,7 @@ public virtual Expression Process(Expression expression) // and now that we have created new SelectExpression we add it to the proper dictionary that we will use for rewrite foreach (var columnToRewrite in columnsToRewrite) { - _columnsToRewrite.Add(columnToRewrite.Key, (newSelectExpression, columnToRewrite.Value)); + _columnsToRewrite.Add(columnToRewrite.Key, columnToRewrite.Value); } // Record the OPENJSON expression and its projected column(s), along with the store type we just removed from the WITH @@ -165,25 +163,17 @@ public virtual Expression Process(Expression expression) return result; } - case ColumnExpression columnExpression: + case ColumnExpression columnExpression + when _columnsToRewrite.TryGetValue((columnExpression.TableAlias, columnExpression.Name), out var columnInfo): { - var table = columnExpression.Table.UnwrapJoin(); - return table is SqlServerOpenJsonExpression openJsonTable - && _columnsToRewrite.TryGetValue((openJsonTable, columnExpression.Name), out var columnRewriteInfo) - ? RewriteOpenJsonColumn(columnExpression, columnRewriteInfo.SelectExpression, columnRewriteInfo.ColumnInfo) - : base.Visit(expression); + return RewriteOpenJsonColumn(columnExpression, columnInfo); } // JsonScalarExpression over a column coming out of OPENJSON/WITH; this means that the column represents an owned sub- // entity, and therefore must have AS JSON. Rewrite the column and simply collapse the paths together. - case JsonScalarExpression - { - Json: ColumnExpression { Table: SqlServerOpenJsonExpression openJsonTable } columnExpression - } jsonScalarExpression - when _columnsToRewrite.TryGetValue((openJsonTable, columnExpression.Name), out var columnRewriteInfo): + case JsonScalarExpression { Json: ColumnExpression columnExpression } jsonScalarExpression + when _columnsToRewrite.TryGetValue((columnExpression.TableAlias, columnExpression.Name), out var columnInfo): { - var (selectExpression, columnInfo) = columnRewriteInfo; - Check.DebugAssert( columnInfo.AsJson, "JsonScalarExpression over a column coming out of OPENJSON is only valid when that column represents an owned " @@ -191,8 +181,8 @@ when _columnsToRewrite.TryGetValue((openJsonTable, columnExpression.Name), out v // The new OPENJSON (without WITH) always projects a `value` column, instead of a properly named column for individual // values inside; create a new ColumnExpression with that name. - SqlExpression rewrittenColumn = selectExpression.CreateColumnExpression( - columnExpression.Table, "value", columnExpression.Type, _nvarcharMaxTypeMapping, columnExpression.IsNullable); + SqlExpression rewrittenColumn = new ColumnExpression( + "value", columnExpression.TableAlias, columnExpression.Type, _nvarcharMaxTypeMapping, columnExpression.IsNullable); // Prepend the path from the OPENJSON/WITH to the path in the JsonScalarExpression var path = columnInfo.Path is null @@ -208,20 +198,16 @@ when _columnsToRewrite.TryGetValue((openJsonTable, columnExpression.Name), out v return base.Visit(expression); } - static bool IsKeyColumn(SqlExpression sqlExpression, TableExpressionBase table) - => (sqlExpression is ColumnExpression { Name: "key", Table: var keyColumnTable } - && keyColumnTable == table) + static bool IsKeyColumn(SqlExpression sqlExpression, string openJsonTableAlias) + => (sqlExpression is ColumnExpression { Name: "key", TableAlias: var tableAlias } && tableAlias == openJsonTableAlias) || (sqlExpression is SqlUnaryExpression { OperatorType: ExpressionType.Convert, Operand: SqlExpression operand } - && IsKeyColumn(operand, table)); + && IsKeyColumn(operand, openJsonTableAlias)); - SqlExpression RewriteOpenJsonColumn( - ColumnExpression columnExpression, - SelectExpression selectExpression, - SqlServerOpenJsonExpression.ColumnInfo columnInfo) + SqlExpression RewriteOpenJsonColumn(ColumnExpression columnExpression, ColumnInfo columnInfo) { // We found a ColumnExpression that refers to the OPENJSON table, we need to rewrite it. @@ -235,8 +221,8 @@ SqlExpression RewriteOpenJsonColumn( // The new OPENJSON (without WITH) always projects a `value` column, instead of a properly named column for individual // values inside; create a new ColumnExpression with that name. - SqlExpression rewrittenColumn = selectExpression.CreateColumnExpression( - columnExpression.Table, "value", columnExpression.Type, _nvarcharMaxTypeMapping, columnExpression.IsNullable); + SqlExpression rewrittenColumn = new ColumnExpression( + "value", columnExpression.TableAlias, columnExpression.Type, _nvarcharMaxTypeMapping, columnExpression.IsNullable); Check.DebugAssert(columnInfo.Path is not null, "Path shouldn't be null in OPENJSON WITH"); //Check.DebugAssert( diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs index a9e42f31cce..413da4c9ca3 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryTranslationPostprocessor.cs @@ -44,12 +44,12 @@ public SqlServerQueryTranslationPostprocessor( /// public override Expression Process(Expression query) { - query = base.Process(query); + var query1 = base.Process(query); - query = _jsonPostprocessor.Process(query); - _skipWithoutOrderByInSplitQueryVerifier.Visit(query); + var query2 = _jsonPostprocessor.Process(query1); + _skipWithoutOrderByInSplitQueryVerifier.Visit(query2); - return query; + return query2; } /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs index 4be55ec472a..7b6792f5408 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQueryableMethodTranslatingExpressionVisitor.cs @@ -448,10 +448,10 @@ static IEnumerable GetAllNavigationsInHierarchy(IEntityType entityT Limit: null, Offset: null, Orderings: [], - Projection: [{ Expression: ColumnExpression { Name: "value", Table: var projectionColumnTable } }] + Projection: [{ Expression: ColumnExpression { Name: "value", TableAlias: var projectionTableAlias } }] } } - && projectionColumnTable == openJsonExpression) + && projectionTableAlias == openJsonExpression.Alias) { var newInExpression = _sqlExpressionFactory.In(translatedItem, parameter); #pragma warning disable EF1001 @@ -492,13 +492,13 @@ static IEnumerable GetAllNavigationsInHierarchy(IEntityType entityT Expression: SqlUnaryExpression { OperatorType: ExpressionType.Convert, - Operand: ColumnExpression { Name: "key", Table: var orderingTable } + Operand: ColumnExpression { Name: "key", TableAlias: var orderingTableAlias } } } ] } selectExpression && TranslateExpression(index) is { } translatedIndex - && orderingTable == openJsonExpression) + && orderingTableAlias == openJsonExpression.Alias) { // Index on JSON array @@ -566,13 +566,13 @@ protected override bool IsNaturallyOrdered(SelectExpression selectExpression) Expression: SqlUnaryExpression { OperatorType: ExpressionType.Convert, - Operand: ColumnExpression { Name: "key", Table: var orderingTable } + Operand: ColumnExpression { Name: "key", TableAlias: var orderingTableAlias } }, IsAscending: true } ] } - && orderingTable == openJsonExpression; + && orderingTableAlias == openJsonExpression.Alias; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -600,11 +600,7 @@ protected override bool IsValidSelectExpressionForExecuteDelete( var projectionBindingExpression = (ProjectionBindingExpression)shaper.ValueBufferExpression; var projection = (StructuralTypeProjectionExpression)selectExpression.GetProjection(projectionBindingExpression); var column = projection.BindProperty(shaper.StructuralType.GetProperties().First()); - table = column.Table; - if (table is JoinExpressionBase joinExpressionBase) - { - table = joinExpressionBase.Table; - } + table = selectExpression.GetTable(column).UnwrapJoin(); } if (table is TableExpression te) @@ -701,7 +697,7 @@ public TemporalAnnotationApplyingExpressionVisitor(Func protected override Expression ApplyInferredTypeMappings( Expression expression, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) => new SqlServerInferredTypeMappingApplier( RelationalDependencies.Model, _typeMappingSource, _sqlExpressionFactory, inferredTypeMappings).Visit(expression); @@ -725,7 +721,7 @@ public SqlServerInferredTypeMappingApplier( IModel model, IRelationalTypeMappingSource typeMappingSource, ISqlExpressionFactory sqlExpressionFactory, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) : base(model, sqlExpressionFactory, inferredTypeMappings) { _typeMappingSource = typeMappingSource; @@ -741,7 +737,7 @@ protected override Expression VisitExtension(Expression expression) => expression switch { SqlServerOpenJsonExpression openJsonExpression - when TryGetInferredTypeMapping(openJsonExpression, "value", out var typeMapping) + when TryGetInferredTypeMapping(openJsonExpression.Alias, "value", out var typeMapping) => ApplyTypeMappingsOnOpenJsonExpression(openJsonExpression, new[] { typeMapping }), _ => base.VisitExtension(expression) diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTreePruner.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTreePruner.cs index ea9264f4469..8834ae1c2a7 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTreePruner.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTreePruner.cs @@ -28,7 +28,7 @@ protected override Expression VisitExtension(Expression node) var visitedJson = (SqlExpression)Visit(openJson.JsonExpression); #pragma warning disable EF1001 // ReferencedColumnMap is pubternal; should be made protected - if (ReferencedColumnMap.TryGetValue(openJson, out var referencedAliases)) + if (ReferencedColumnMap.TryGetValue(openJson.Alias, out var referencedAliases)) #pragma warning restore EF1001 { List? newColumnInfos = null; diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs index 99c085280f7..c70c45edfd0 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQueryableMethodTranslatingExpressionVisitor.cs @@ -465,7 +465,7 @@ static IEnumerable GetAllNavigationsInHierarchy(IEntityType entityT Limit: null, Offset: null } selectExpression - && orderingColumn.Table == jsonEachExpression + && orderingColumn.TableAlias == jsonEachExpression.Alias && TranslateExpression(index) is { } translatedIndex) { // Index on JSON array @@ -520,19 +520,20 @@ protected override bool IsNaturallyOrdered(SelectExpression selectExpression) Orderings: [ { - Expression: ColumnExpression { Name: "key", Table: var orderingTable } orderingColumn, + Expression: ColumnExpression { Name: "key" } orderingColumn, IsAscending: true } ] } - && orderingTable == mainTable - && IsJsonEachKeyColumn(orderingColumn); - - bool IsJsonEachKeyColumn(ColumnExpression orderingColumn) - => orderingColumn.Table is JsonEachExpression - || (orderingColumn.Table is SelectExpression subquery - && subquery.Projection.FirstOrDefault(p => p.Alias == "key")?.Expression is ColumnExpression projectedColumn - && IsJsonEachKeyColumn(projectedColumn)); + && orderingColumn.TableAlias == mainTable.Alias + && IsJsonEachKeyColumn(selectExpression, orderingColumn); + + bool IsJsonEachKeyColumn(SelectExpression selectExpression, ColumnExpression orderingColumn) + => selectExpression.Tables.FirstOrDefault(t => t.Alias == orderingColumn.TableAlias)?.UnwrapJoin() is TableExpressionBase table + && (table is JsonEachExpression + || (table is SelectExpression subquery + && subquery.Projection.FirstOrDefault(p => p.Alias == "key")?.Expression is ColumnExpression projectedColumn + && IsJsonEachKeyColumn(subquery, projectedColumn))); } private static Type GetProviderType(SqlExpression expression) @@ -548,7 +549,7 @@ private static Type GetProviderType(SqlExpression expression) /// protected override Expression ApplyInferredTypeMappings( Expression expression, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) => new SqliteInferredTypeMappingApplier( RelationalDependencies.Model, _typeMappingSource, _sqlExpressionFactory, inferredTypeMappings).Visit(expression); @@ -562,7 +563,7 @@ protected class SqliteInferredTypeMappingApplier : RelationalInferredTypeMapping { private readonly IRelationalTypeMappingSource _typeMappingSource; private readonly SqliteSqlExpressionFactory _sqlExpressionFactory; - private Dictionary? _currentSelectInferredTypeMappings; + private Dictionary? _currentSelectInferredTypeMappings; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -574,7 +575,7 @@ public SqliteInferredTypeMappingApplier( IModel model, IRelationalTypeMappingSource typeMappingSource, SqliteSqlExpressionFactory sqlExpressionFactory, - IReadOnlyDictionary<(TableExpressionBase, string), RelationalTypeMapping?> inferredTypeMappings) + IReadOnlyDictionary<(string, string), RelationalTypeMapping?> inferredTypeMappings) : base(model, sqlExpressionFactory, inferredTypeMappings) { (_typeMappingSource, _sqlExpressionFactory) = (typeMappingSource, sqlExpressionFactory); @@ -591,7 +592,7 @@ protected override Expression VisitExtension(Expression expression) switch (expression) { case TableValuedFunctionExpression { Name: "json_each", Schema: null, IsBuiltIn: true } jsonEachExpression - when TryGetInferredTypeMapping(jsonEachExpression, "value", out var typeMapping): + when TryGetInferredTypeMapping(jsonEachExpression.Alias, "value", out var typeMapping): return ApplyTypeMappingsOnJsonEachExpression(jsonEachExpression, typeMapping); // Above, we applied the type mapping to the parameter that json_each accepts as an argument. @@ -600,20 +601,20 @@ when TryGetInferredTypeMapping(jsonEachExpression, "value", out var typeMapping) // in the immediate SelectExpression, and continue visiting down (see ColumnExpression visitation below). case SelectExpression selectExpression: { - Dictionary? previousSelectInferredTypeMappings = null; + Dictionary? previousSelectInferredTypeMappings = null; foreach (var table in selectExpression.Tables) { if (table is TableValuedFunctionExpression { Name: "json_each", Schema: null, IsBuiltIn: true } jsonEachExpression - && TryGetInferredTypeMapping(jsonEachExpression, "value", out var inferredTypeMapping)) + && TryGetInferredTypeMapping(jsonEachExpression.Alias, "value", out var inferredTypeMapping)) { if (previousSelectInferredTypeMappings is null) { previousSelectInferredTypeMappings = _currentSelectInferredTypeMappings; - _currentSelectInferredTypeMappings = new Dictionary(); + _currentSelectInferredTypeMappings = new Dictionary(); } - _currentSelectInferredTypeMappings![jsonEachExpression] = inferredTypeMapping; + _currentSelectInferredTypeMappings![jsonEachExpression.Alias] = inferredTypeMapping; } } @@ -628,7 +629,7 @@ when TryGetInferredTypeMapping(jsonEachExpression, "value", out var typeMapping) // opposed to parameter collections, where the type mapping needs to be inferred). This is in order to apply SQL conversion // logic later in the process, see note in TranslateCollection. case ColumnExpression { Name: "value" } columnExpression - when _currentSelectInferredTypeMappings?.TryGetValue(columnExpression.Table, out var inferredTypeMapping) is true: + when _currentSelectInferredTypeMappings?.TryGetValue(columnExpression.TableAlias, out var inferredTypeMapping) is true: return ApplyJsonSqlConversion( columnExpression.ApplyTypeMapping(inferredTypeMapping), _sqlExpressionFactory, diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs index c5785bfcf1a..1042a432aab 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesSqlServerTest.cs @@ -197,20 +197,20 @@ public override async Task Update_complex_type_to_another_database_complex_type_ """ @__p_0='1' -UPDATE [c] -SET [c].[ShippingAddress_AddressLine1] = [t].[BillingAddress_AddressLine1], - [c].[ShippingAddress_AddressLine2] = [t].[BillingAddress_AddressLine2], - [c].[ShippingAddress_Tags] = [t].[BillingAddress_Tags], - [c].[ShippingAddress_ZipCode] = [t].[BillingAddress_ZipCode], - [c].[ShippingAddress_Country_Code] = [t].[ShippingAddress_Country_Code], - [c].[ShippingAddress_Country_FullName] = [t].[ShippingAddress_Country_FullName] -FROM [Customer] AS [c] +UPDATE [c0] +SET [c0].[ShippingAddress_AddressLine1] = [t].[BillingAddress_AddressLine1], + [c0].[ShippingAddress_AddressLine2] = [t].[BillingAddress_AddressLine2], + [c0].[ShippingAddress_Tags] = [t].[BillingAddress_Tags], + [c0].[ShippingAddress_ZipCode] = [t].[BillingAddress_ZipCode], + [c0].[ShippingAddress_Country_Code] = [t].[ShippingAddress_Country_Code], + [c0].[ShippingAddress_Country_FullName] = [t].[ShippingAddress_Country_FullName] +FROM [Customer] AS [c0] INNER JOIN ( - SELECT [c0].[Id], [c0].[Name], [c0].[BillingAddress_AddressLine1], [c0].[BillingAddress_AddressLine2], [c0].[BillingAddress_Tags], [c0].[BillingAddress_ZipCode], [c0].[BillingAddress_Country_Code], [c0].[BillingAddress_Country_FullName], [c0].[ShippingAddress_AddressLine1], [c0].[ShippingAddress_AddressLine2], [c0].[ShippingAddress_Tags], [c0].[ShippingAddress_ZipCode], [c0].[ShippingAddress_Country_Code], [c0].[ShippingAddress_Country_FullName] - FROM [Customer] AS [c0] - ORDER BY [c0].[Id] + SELECT [c].[Id], [c].[BillingAddress_AddressLine1], [c].[BillingAddress_AddressLine2], [c].[BillingAddress_Tags], [c].[BillingAddress_ZipCode], [c].[ShippingAddress_Country_Code], [c].[ShippingAddress_Country_FullName] + FROM [Customer] AS [c] + ORDER BY [c].[Id] OFFSET @__p_0 ROWS -) AS [t] ON [c].[Id] = [t].[Id] +) AS [t] ON [c0].[Id] = [t].[Id] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs index 6542ca2a3be..b7f0200c6c4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs @@ -446,7 +446,7 @@ public override async Task Tpc_entity_owning_a_split_reference_on_leaf_with_tabl AssertSql( """ -SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [l].[Id], [l].[OwnedReference_Id], [l].[OwnedReference_OwnedIntValue1], [l].[OwnedReference_OwnedIntValue2], [o0].[OwnedIntValue3], [o].[OwnedIntValue4], [l].[OwnedReference_OwnedStringValue1], [l].[OwnedReference_OwnedStringValue2], [o0].[OwnedStringValue3], [o].[OwnedStringValue4] +SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [l0].[Id], [l0].[OwnedReference_Id], [l0].[OwnedReference_OwnedIntValue1], [l0].[OwnedReference_OwnedIntValue2], [o0].[OwnedIntValue3], [o].[OwnedIntValue4], [l0].[OwnedReference_OwnedStringValue1], [l0].[OwnedReference_OwnedStringValue2], [o0].[OwnedStringValue3], [o].[OwnedStringValue4] FROM ( SELECT [b].[Id], [b].[BaseValue], NULL AS [MiddleValue], NULL AS [SiblingValue], NULL AS [LeafValue], N'BaseEntity' AS [Discriminator] FROM [BaseEntity] AS [b] @@ -457,12 +457,12 @@ UNION ALL SELECT [s].[Id], [s].[BaseValue], NULL AS [MiddleValue], [s].[SiblingValue], NULL AS [LeafValue], N'SiblingEntity' AS [Discriminator] FROM [SiblingEntity] AS [s] UNION ALL - SELECT [l0].[Id], [l0].[BaseValue], [l0].[MiddleValue], NULL AS [SiblingValue], [l0].[LeafValue], N'LeafEntity' AS [Discriminator] - FROM [LeafEntity] AS [l0] + SELECT [l].[Id], [l].[BaseValue], [l].[MiddleValue], NULL AS [SiblingValue], [l].[LeafValue], N'LeafEntity' AS [Discriminator] + FROM [LeafEntity] AS [l] ) AS [t] -LEFT JOIN [LeafEntity] AS [l] ON [t].[Id] = [l].[Id] -LEFT JOIN [OwnedReferencePart4] AS [o] ON [l].[Id] = [o].[LeafEntityId] -LEFT JOIN [OwnedReferencePart3] AS [o0] ON [l].[Id] = [o0].[LeafEntityId] +LEFT JOIN [LeafEntity] AS [l0] ON [t].[Id] = [l0].[Id] +LEFT JOIN [OwnedReferencePart4] AS [o] ON [l0].[Id] = [o].[LeafEntityId] +LEFT JOIN [OwnedReferencePart3] AS [o0] ON [l0].[Id] = [o0].[LeafEntityId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index 74b9b246c7f..595baa2f8f8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -388,7 +388,7 @@ public override async Task Default_if_empty_top_level(bool async) SELECT [t].[EmployeeID], [t].[City], [t].[Country], [t].[FirstName], [t].[ReportsTo], [t].[Title] FROM ( SELECT 1 AS empty -) AS [e] +) AS [e0] LEFT JOIN ( SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title] FROM [Employees] AS [e] @@ -406,7 +406,7 @@ public override async Task Join_with_default_if_empty_on_both_sources(bool async SELECT [t].[EmployeeID], [t].[City], [t].[Country], [t].[FirstName], [t].[ReportsTo], [t].[Title] FROM ( SELECT 1 AS empty -) AS [e] +) AS [e0] LEFT JOIN ( SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title] FROM [Employees] AS [e] @@ -416,11 +416,11 @@ INNER JOIN ( SELECT [t0].[EmployeeID] FROM ( SELECT 1 AS empty - ) AS [e] + ) AS [e2] LEFT JOIN ( - SELECT [e0].[EmployeeID] - FROM [Employees] AS [e0] - WHERE [e0].[EmployeeID] = -1 + SELECT [e1].[EmployeeID] + FROM [Employees] AS [e1] + WHERE [e1].[EmployeeID] = -1 ) AS [t0] ON 1 = 1 ) AS [t1] ON [t].[EmployeeID] = [t1].[EmployeeID] """); @@ -435,7 +435,7 @@ public override async Task Default_if_empty_top_level_followed_by_projecting_con SELECT N'Foo' FROM ( SELECT 1 AS empty -) AS [e] +) AS [e0] LEFT JOIN ( SELECT 1 AS empty FROM [Employees] AS [e] @@ -453,7 +453,7 @@ public override async Task Default_if_empty_top_level_positive(bool async) SELECT [t].[EmployeeID], [t].[City], [t].[Country], [t].[FirstName], [t].[ReportsTo], [t].[Title] FROM ( SELECT 1 AS empty -) AS [e] +) AS [e0] LEFT JOIN ( SELECT [e].[EmployeeID], [e].[City], [e].[Country], [e].[FirstName], [e].[ReportsTo], [e].[Title] FROM [Employees] AS [e] @@ -471,7 +471,7 @@ public override async Task Default_if_empty_top_level_projection(bool async) SELECT COALESCE([t].[EmployeeID], 0) FROM ( SELECT 1 AS empty -) AS [e] +) AS [e0] LEFT JOIN ( SELECT [e].[EmployeeID] FROM [Employees] AS [e] @@ -5316,7 +5316,7 @@ WHEN EXISTS ( SELECT 1 FROM ( SELECT 1 AS empty - ) AS [e] + ) AS [e0] LEFT JOIN ( SELECT 1 AS empty FROM [Employees] AS [e] diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 61eeb46391e..47bb6c42213 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -5924,31 +5924,31 @@ FROM [Officers] AS [o] ) AS [t] LEFT JOIN [Tags] AS [t0] ON [t].[Nickname] = [t0].[GearNickName] AND [t].[SquadId] = [t0].[GearSquadId] LEFT JOIN ( - SELECT [g].[Nickname], [g].[SquadId], [g].[FullName] - FROM [Gears] AS [g] + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] + FROM [Gears] AS [g0] UNION ALL - SELECT [o0].[Nickname], [o0].[SquadId], [o0].[FullName] - FROM [Officers] AS [o0] + SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] + FROM [Officers] AS [o1] ) AS [t2] ON [t0].[GearNickName] = [t2].[Nickname] AND [t0].[GearSquadId] = [t2].[SquadId] LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], [t3].[Nickname], [t3].[SquadId] FROM [Weapons] AS [w] LEFT JOIN ( - SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] - FROM [Gears] AS [g0] + SELECT [g1].[Nickname], [g1].[SquadId], [g1].[FullName] + FROM [Gears] AS [g1] UNION ALL - SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] - FROM [Officers] AS [o1] + SELECT [o2].[Nickname], [o2].[SquadId], [o2].[FullName] + FROM [Officers] AS [o2] ) AS [t3] ON [w].[OwnerFullName] = [t3].[FullName] ) AS [t4] ON [t2].[FullName] = [t4].[OwnerFullName] WHERE EXISTS ( SELECT 1 FROM ( - SELECT [g1].[LeaderNickname], [g1].[LeaderSquadId] - FROM [Gears] AS [g1] + SELECT [g].[LeaderNickname], [g].[LeaderSquadId] + FROM [Gears] AS [g] UNION ALL - SELECT [o2].[LeaderNickname], [o2].[LeaderSquadId] - FROM [Officers] AS [o2] + SELECT [o0].[LeaderNickname], [o0].[LeaderSquadId] + FROM [Officers] AS [o0] ) AS [t1] WHERE [t].[Nickname] = [t1].[LeaderNickname] AND [t].[SquadId] = [t1].[LeaderSquadId]) ORDER BY [t].[HasSoulPatch] DESC, [t0].[Note], [t].[Nickname], [t].[SquadId], [t0].[Id], [t2].[Nickname], [t2].[SquadId], [t4].[IsAutomatic], [t4].[Nickname] DESC, [t4].[Id] @@ -5969,31 +5969,31 @@ FROM [Officers] AS [o] ) AS [t] LEFT JOIN [Tags] AS [t0] ON [t].[Nickname] = [t0].[GearNickName] AND [t].[SquadId] = [t0].[GearSquadId] LEFT JOIN ( - SELECT [g].[Nickname], [g].[SquadId], [g].[FullName] - FROM [Gears] AS [g] + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] + FROM [Gears] AS [g0] UNION ALL - SELECT [o0].[Nickname], [o0].[SquadId], [o0].[FullName] - FROM [Officers] AS [o0] + SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] + FROM [Officers] AS [o1] ) AS [t2] ON [t0].[GearNickName] = [t2].[Nickname] AND [t0].[GearSquadId] = [t2].[SquadId] LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], [t3].[Nickname], [t3].[SquadId] FROM [Weapons] AS [w] LEFT JOIN ( - SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] - FROM [Gears] AS [g0] + SELECT [g1].[Nickname], [g1].[SquadId], [g1].[FullName] + FROM [Gears] AS [g1] UNION ALL - SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] - FROM [Officers] AS [o1] + SELECT [o2].[Nickname], [o2].[SquadId], [o2].[FullName] + FROM [Officers] AS [o2] ) AS [t3] ON [w].[OwnerFullName] = [t3].[FullName] ) AS [t4] ON [t2].[FullName] = [t4].[OwnerFullName] WHERE EXISTS ( SELECT 1 FROM ( - SELECT [g1].[LeaderNickname], [g1].[LeaderSquadId] - FROM [Gears] AS [g1] + SELECT [g].[LeaderNickname], [g].[LeaderSquadId] + FROM [Gears] AS [g] UNION ALL - SELECT [o2].[LeaderNickname], [o2].[LeaderSquadId] - FROM [Officers] AS [o2] + SELECT [o0].[LeaderNickname], [o0].[LeaderSquadId] + FROM [Officers] AS [o0] ) AS [t1] WHERE [t].[Nickname] = [t1].[LeaderNickname] AND [t].[SquadId] = [t1].[LeaderSquadId]) ORDER BY [t].[HasSoulPatch] DESC, [t0].[Note], [t].[Nickname], [t].[SquadId], [t0].[Id], [t2].[Nickname], [t2].[SquadId], [t4].[IsAutomatic], [t4].[Nickname] DESC, [t4].[Id] @@ -6014,11 +6014,11 @@ FROM [Officers] AS [o] ) AS [t] LEFT JOIN [Tags] AS [t0] ON [t].[Nickname] = [t0].[GearNickName] AND [t].[SquadId] = [t0].[GearSquadId] LEFT JOIN ( - SELECT [g].[Nickname], [g].[SquadId], [g].[FullName] - FROM [Gears] AS [g] + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] + FROM [Gears] AS [g0] UNION ALL - SELECT [o0].[Nickname], [o0].[SquadId], [o0].[FullName] - FROM [Officers] AS [o0] + SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] + FROM [Officers] AS [o1] ) AS [t2] ON [t0].[GearNickName] = [t2].[Nickname] AND [t0].[GearSquadId] = [t2].[SquadId] LEFT JOIN ( SELECT [w].[Id], [w].[AmmunitionType], [w].[IsAutomatic], [w].[Name], [w].[OwnerFullName], [w].[SynergyWithId], [t3].[Nickname], [t3].[SquadId], ( @@ -6027,21 +6027,21 @@ FROM [Weapons] AS [w0] WHERE [t3].[FullName] IS NOT NULL AND [t3].[FullName] = [w0].[OwnerFullName]) AS [c] FROM [Weapons] AS [w] LEFT JOIN ( - SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] - FROM [Gears] AS [g0] + SELECT [g1].[Nickname], [g1].[SquadId], [g1].[FullName] + FROM [Gears] AS [g1] UNION ALL - SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] - FROM [Officers] AS [o1] + SELECT [o2].[Nickname], [o2].[SquadId], [o2].[FullName] + FROM [Officers] AS [o2] ) AS [t3] ON [w].[OwnerFullName] = [t3].[FullName] ) AS [t4] ON [t2].[FullName] = [t4].[OwnerFullName] WHERE EXISTS ( SELECT 1 FROM ( - SELECT [g1].[LeaderNickname], [g1].[LeaderSquadId] - FROM [Gears] AS [g1] + SELECT [g].[LeaderNickname], [g].[LeaderSquadId] + FROM [Gears] AS [g] UNION ALL - SELECT [o2].[LeaderNickname], [o2].[LeaderSquadId] - FROM [Officers] AS [o2] + SELECT [o0].[LeaderNickname], [o0].[LeaderSquadId] + FROM [Officers] AS [o0] ) AS [t1] WHERE [t].[Nickname] = [t1].[LeaderNickname] AND [t].[SquadId] = [t1].[LeaderSquadId]) ORDER BY [t].[HasSoulPatch] DESC, [t0].[Note], [t].[Nickname], [t].[SquadId], [t0].[Id], [t2].[Nickname], [t2].[SquadId], [t4].[Id] DESC, [t4].[c], [t4].[Nickname] @@ -6061,39 +6061,39 @@ FROM [Officers] AS [o] ) AS [t] LEFT JOIN [Tags] AS [t0] ON [t].[Nickname] = [t0].[GearNickName] AND [t].[SquadId] = [t0].[GearSquadId] LEFT JOIN ( - SELECT [g].[Nickname], [g].[SquadId], [g].[FullName] - FROM [Gears] AS [g] + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName] + FROM [Gears] AS [g0] UNION ALL - SELECT [o0].[Nickname], [o0].[SquadId], [o0].[FullName] - FROM [Officers] AS [o0] + SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName] + FROM [Officers] AS [o1] ) AS [t2] ON [t0].[GearNickName] = [t2].[Nickname] AND [t0].[GearSquadId] = [t2].[SquadId] LEFT JOIN ( SELECT [t3].[FullName], [t3].[Nickname], [t3].[SquadId], [t7].[Id], [t7].[Nickname] AS [Nickname0], [t7].[SquadId] AS [SquadId0], [t7].[Id0], [t7].[Name], [t7].[IsAutomatic], [t7].[Id1], [t7].[Nickname0] AS [Nickname00], [t7].[HasSoulPatch], [t7].[SquadId0] AS [SquadId00], [t3].[Rank], [t7].[IsAutomatic0], [t3].[LeaderNickname], [t3].[LeaderSquadId] FROM ( - SELECT [g0].[Nickname], [g0].[SquadId], [g0].[FullName], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank] - FROM [Gears] AS [g0] + SELECT [g1].[Nickname], [g1].[SquadId], [g1].[FullName], [g1].[LeaderNickname], [g1].[LeaderSquadId], [g1].[Rank] + FROM [Gears] AS [g1] UNION ALL - SELECT [o1].[Nickname], [o1].[SquadId], [o1].[FullName], [o1].[LeaderNickname], [o1].[LeaderSquadId], [o1].[Rank] - FROM [Officers] AS [o1] + SELECT [o2].[Nickname], [o2].[SquadId], [o2].[FullName], [o2].[LeaderNickname], [o2].[LeaderSquadId], [o2].[Rank] + FROM [Officers] AS [o2] ) AS [t3] LEFT JOIN ( SELECT [w].[Id], [t4].[Nickname], [t4].[SquadId], [s].[Id] AS [Id0], [w0].[Name], [w0].[IsAutomatic], [w0].[Id] AS [Id1], [t5].[Nickname] AS [Nickname0], [t5].[HasSoulPatch], [t5].[SquadId] AS [SquadId0], [w].[IsAutomatic] AS [IsAutomatic0], [w].[OwnerFullName] FROM [Weapons] AS [w] LEFT JOIN ( - SELECT [g1].[Nickname], [g1].[SquadId], [g1].[FullName] - FROM [Gears] AS [g1] + SELECT [g2].[Nickname], [g2].[SquadId], [g2].[FullName] + FROM [Gears] AS [g2] UNION ALL - SELECT [o2].[Nickname], [o2].[SquadId], [o2].[FullName] - FROM [Officers] AS [o2] + SELECT [o3].[Nickname], [o3].[SquadId], [o3].[FullName] + FROM [Officers] AS [o3] ) AS [t4] ON [w].[OwnerFullName] = [t4].[FullName] LEFT JOIN [Squads] AS [s] ON [t4].[SquadId] = [s].[Id] LEFT JOIN [Weapons] AS [w0] ON [t4].[FullName] = [w0].[OwnerFullName] LEFT JOIN ( - SELECT [g2].[Nickname], [g2].[SquadId], [g2].[HasSoulPatch] - FROM [Gears] AS [g2] + SELECT [g3].[Nickname], [g3].[SquadId], [g3].[HasSoulPatch] + FROM [Gears] AS [g3] UNION ALL - SELECT [o3].[Nickname], [o3].[SquadId], [o3].[HasSoulPatch] - FROM [Officers] AS [o3] + SELECT [o4].[Nickname], [o4].[SquadId], [o4].[HasSoulPatch] + FROM [Officers] AS [o4] ) AS [t5] ON [s].[Id] = [t5].[SquadId] WHERE [w].[Name] <> N'Bar' OR [w].[Name] IS NULL ) AS [t7] ON [t3].[FullName] = [t7].[OwnerFullName] @@ -6103,21 +6103,21 @@ LEFT JOIN ( SELECT [w1].[Id], [w1].[AmmunitionType], [w1].[IsAutomatic], [w1].[Name], [w1].[OwnerFullName], [w1].[SynergyWithId], [t6].[Nickname], [t6].[SquadId] FROM [Weapons] AS [w1] LEFT JOIN ( - SELECT [g3].[Nickname], [g3].[SquadId], [g3].[FullName] - FROM [Gears] AS [g3] + SELECT [g4].[Nickname], [g4].[SquadId], [g4].[FullName] + FROM [Gears] AS [g4] UNION ALL - SELECT [o4].[Nickname], [o4].[SquadId], [o4].[FullName] - FROM [Officers] AS [o4] + SELECT [o5].[Nickname], [o5].[SquadId], [o5].[FullName] + FROM [Officers] AS [o5] ) AS [t6] ON [w1].[OwnerFullName] = [t6].[FullName] ) AS [t9] ON [t2].[FullName] = [t9].[OwnerFullName] WHERE EXISTS ( SELECT 1 FROM ( - SELECT [g4].[LeaderNickname], [g4].[LeaderSquadId] - FROM [Gears] AS [g4] + SELECT [g].[LeaderNickname], [g].[LeaderSquadId] + FROM [Gears] AS [g] UNION ALL - SELECT [o5].[LeaderNickname], [o5].[LeaderSquadId] - FROM [Officers] AS [o5] + SELECT [o0].[LeaderNickname], [o0].[LeaderSquadId] + FROM [Officers] AS [o0] ) AS [t1] WHERE [t].[Nickname] = [t1].[LeaderNickname] AND [t].[SquadId] = [t1].[LeaderSquadId]) ORDER BY [t].[HasSoulPatch] DESC, [t0].[Note], [t].[Nickname], [t].[SquadId], [t0].[Id], [t2].[Nickname], [t2].[SquadId], [t8].[Rank], [t8].[Nickname], [t8].[SquadId], [t8].[IsAutomatic0], [t8].[Id], [t8].[Nickname0], [t8].[SquadId0], [t8].[Id0], [t8].[Id1], [t8].[Nickname00], [t8].[SquadId00], [t9].[IsAutomatic], [t9].[Nickname] DESC, [t9].[Id] @@ -6767,16 +6767,16 @@ public override async Task Null_semantics_on_nullable_bool_from_inner_join_subqu """ SELECT [t0].[Id], [t0].[CapitalName], [t0].[Name], [t0].[ServerAddress], [t0].[CommanderName], [t0].[Eradicated] FROM ( - SELECT [l0].[Name] - FROM [LocustLeaders] AS [l0] + SELECT [l].[Name] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[Name] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name] + FROM [LocustCommanders] AS [l0] ) AS [t] INNER JOIN ( - SELECT [l].[Id], [l].[CapitalName], [l].[Name], [l].[ServerAddress], [l].[CommanderName], [l].[Eradicated] - FROM [LocustHordes] AS [l] - WHERE [l].[Name] = N'Swarm' + SELECT [l1].[Id], [l1].[CapitalName], [l1].[Name], [l1].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated] + FROM [LocustHordes] AS [l1] + WHERE [l1].[Name] = N'Swarm' ) AS [t0] ON [t].[Name] = [t0].[CommanderName] WHERE [t0].[Eradicated] <> CAST(1 AS bit) OR [t0].[Eradicated] IS NULL """); @@ -6790,16 +6790,16 @@ public override async Task Null_semantics_on_nullable_bool_from_left_join_subque """ SELECT [t0].[Id], [t0].[CapitalName], [t0].[Name], [t0].[ServerAddress], [t0].[CommanderName], [t0].[Eradicated] FROM ( - SELECT [l0].[Name] - FROM [LocustLeaders] AS [l0] + SELECT [l].[Name] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[Name] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name] + FROM [LocustCommanders] AS [l0] ) AS [t] LEFT JOIN ( - SELECT [l].[Id], [l].[CapitalName], [l].[Name], [l].[ServerAddress], [l].[CommanderName], [l].[Eradicated] - FROM [LocustHordes] AS [l] - WHERE [l].[Name] = N'Swarm' + SELECT [l1].[Id], [l1].[CapitalName], [l1].[Name], [l1].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated] + FROM [LocustHordes] AS [l1] + WHERE [l1].[Name] = N'Swarm' ) AS [t0] ON [t].[Name] = [t0].[CommanderName] WHERE [t0].[Eradicated] <> CAST(1 AS bit) OR [t0].[Eradicated] IS NULL """); @@ -6844,15 +6844,15 @@ public override async Task Select_required_navigation_on_derived_type(bool async AssertSql( """ -SELECT [l].[Name] +SELECT [l1].[Name] FROM ( SELECT NULL AS [HighCommandId] - FROM [LocustLeaders] AS [l0] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[HighCommandId] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[HighCommandId] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustHighCommands] AS [l] ON [t].[HighCommandId] = [l].[Id] +LEFT JOIN [LocustHighCommands] AS [l1] ON [t].[HighCommandId] = [l1].[Id] """); } @@ -6882,14 +6882,14 @@ public override async Task Where_required_navigation_on_derived_type(bool async) """ SELECT [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] FROM ( - SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] - FROM [LocustLeaders] AS [l0] + SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustHighCommands] AS [l] ON [t].[HighCommandId] = [l].[Id] -WHERE [l].[IsOperational] = CAST(1 AS bit) +LEFT JOIN [LocustHighCommands] AS [l1] ON [t].[HighCommandId] = [l1].[Id] +WHERE [l1].[IsOperational] = CAST(1 AS bit) """); } @@ -7022,11 +7022,11 @@ public override async Task Order_by_entity_qsre_with_inheritance(bool async) """ SELECT [t].[Name] FROM ( - SELECT [l0].[Name], [l0].[HighCommandId] - FROM [LocustCommanders] AS [l0] + SELECT [l].[Name], [l].[HighCommandId] + FROM [LocustCommanders] AS [l] ) AS [t] -INNER JOIN [LocustHighCommands] AS [l] ON [t].[HighCommandId] = [l].[Id] -ORDER BY [l].[Id], [t].[Name] +INNER JOIN [LocustHighCommands] AS [l0] ON [t].[HighCommandId] = [l0].[Id] +ORDER BY [l0].[Id], [t].[Name] """); } @@ -7676,11 +7676,11 @@ FROM [Officers] AS [o] LEFT JOIN ( SELECT [t1].[Nickname], [t1].[SquadId], [t1].[AssignedCityName], [t1].[CityOfBirthName], [t1].[FullName], [t1].[HasSoulPatch], [t1].[LeaderNickname], [t1].[LeaderSquadId], [t1].[Rank], [t1].[Discriminator] FROM ( - SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], N'Gear' AS [Discriminator] - FROM [Gears] AS [g] + SELECT [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank], N'Gear' AS [Discriminator] + FROM [Gears] AS [g0] UNION ALL - SELECT [o0].[Nickname], [o0].[SquadId], [o0].[AssignedCityName], [o0].[CityOfBirthName], [o0].[FullName], [o0].[HasSoulPatch], [o0].[LeaderNickname], [o0].[LeaderSquadId], [o0].[Rank], N'Officer' AS [Discriminator] - FROM [Officers] AS [o0] + SELECT [o1].[Nickname], [o1].[SquadId], [o1].[AssignedCityName], [o1].[CityOfBirthName], [o1].[FullName], [o1].[HasSoulPatch], [o1].[LeaderNickname], [o1].[LeaderSquadId], [o1].[Rank], N'Officer' AS [Discriminator] + FROM [Officers] AS [o1] ) AS [t1] WHERE [t1].[HasSoulPatch] = CAST(0 AS bit) ) AS [t2] ON [t].[Nickname] = [t2].[LeaderNickname] AND [t].[SquadId] = [t2].[LeaderSquadId] @@ -7690,11 +7690,11 @@ FROM [Weapons] AS [w] WHERE [t].[FullName] = [w].[OwnerFullName] AND [w].[IsAutomatic] = COALESCE(( SELECT TOP(1) [t0].[HasSoulPatch] FROM ( - SELECT [g0].[Nickname], [g0].[HasSoulPatch] - FROM [Gears] AS [g0] + SELECT [g].[Nickname], [g].[HasSoulPatch] + FROM [Gears] AS [g] UNION ALL - SELECT [o1].[Nickname], [o1].[HasSoulPatch] - FROM [Officers] AS [o1] + SELECT [o0].[Nickname], [o0].[HasSoulPatch] + FROM [Officers] AS [o0] ) AS [t0] WHERE [t0].[Nickname] = N'Marcus'), CAST(0 AS bit))), [t].[Nickname], [t].[SquadId], [t2].[Nickname] """); @@ -9233,13 +9233,13 @@ public override async Task Navigation_based_on_complex_expression4(bool async) AssertSql( """ -SELECT CAST(1 AS bit), [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] +SELECT CAST(1 AS bit), [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] FROM [LocustHordes] AS [l] CROSS JOIN ( - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustCommanders] AS [l0] ON [l].[CommanderName] = [l0].[Name] +LEFT JOIN [LocustCommanders] AS [l1] ON [l].[CommanderName] = [l1].[Name] """); } @@ -9249,13 +9249,13 @@ public override async Task Navigation_based_on_complex_expression5(bool async) AssertSql( """ -SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] +SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] FROM [LocustHordes] AS [l] CROSS JOIN ( - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustCommanders] AS [l0] ON [l].[CommanderName] = [l0].[Name] +LEFT JOIN [LocustCommanders] AS [l1] ON [l].[CommanderName] = [l1].[Name] """); } @@ -9266,15 +9266,15 @@ public override async Task Navigation_based_on_complex_expression6(bool async) AssertSql( """ SELECT CASE - WHEN [l0].[Name] = N'Queen Myrrah' AND [l0].[Name] IS NOT NULL THEN CAST(1 AS bit) + WHEN [l1].[Name] = N'Queen Myrrah' AND [l1].[Name] IS NOT NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END, [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] +END, [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator] FROM [LocustHordes] AS [l] CROSS JOIN ( - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustCommanders] AS [l0] ON [l].[CommanderName] = [l0].[Name] +LEFT JOIN [LocustCommanders] AS [l1] ON [l].[CommanderName] = [l1].[Name] """); } @@ -10095,22 +10095,22 @@ public override async Task Join_inner_source_custom_projection_followed_by_filte AssertSql( """ SELECT CASE - WHEN [l].[Name] = N'Locust' THEN CAST(1 AS bit) + WHEN [l1].[Name] = N'Locust' THEN CAST(1 AS bit) ELSE NULL -END AS [IsEradicated], [l].[CommanderName], [l].[Name] +END AS [IsEradicated], [l1].[CommanderName], [l1].[Name] FROM ( - SELECT [l0].[Name] - FROM [LocustLeaders] AS [l0] + SELECT [l].[Name] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[Name] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name] + FROM [LocustCommanders] AS [l0] ) AS [t] -INNER JOIN [LocustHordes] AS [l] ON [t].[Name] = [l].[CommanderName] +INNER JOIN [LocustHordes] AS [l1] ON [t].[Name] = [l1].[CommanderName] WHERE CASE - WHEN [l].[Name] = N'Locust' THEN CAST(1 AS bit) + WHEN [l1].[Name] = N'Locust' THEN CAST(1 AS bit) ELSE NULL END <> CAST(1 AS bit) OR CASE - WHEN [l].[Name] = N'Locust' THEN CAST(1 AS bit) + WHEN [l1].[Name] = N'Locust' THEN CAST(1 AS bit) ELSE NULL END IS NULL """); @@ -11889,19 +11889,19 @@ public override async Task Project_navigation_defined_on_derived_from_entity_wit SELECT [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator], [t0].[Nickname], [t0].[SquadId], [t0].[AssignedCityName], [t0].[CityOfBirthName], [t0].[FullName], [t0].[HasSoulPatch], [t0].[LeaderNickname], [t0].[LeaderSquadId], [t0].[Rank], [t0].[Discriminator], CASE WHEN [t0].[Nickname] IS NULL OR [t0].[SquadId] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END AS [IsNull], [l].[Id], [l].[CapitalName], [l].[Name], [l].[ServerAddress], [l].[CommanderName], [l].[Eradicated], CASE - WHEN [l].[Id] IS NULL THEN CAST(1 AS bit) +END AS [IsNull], [l1].[Id], [l1].[CapitalName], [l1].[Name], [l1].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated], CASE + WHEN [l1].[Id] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) -END AS [IsNull], [l0].[Id], [l0].[IsOperational], [l0].[Name], CASE - WHEN [l0].[Id] IS NULL THEN CAST(1 AS bit) +END AS [IsNull], [l2].[Id], [l2].[IsOperational], [l2].[Name], CASE + WHEN [l2].[Id] IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS [IsNull] FROM ( - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] - FROM [LocustLeaders] AS [l1] + SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l2].[Name], [l2].[LocustHordeId], [l2].[ThreatLevel], [l2].[ThreatLevelByte], [l2].[ThreatLevelNullableByte], [l2].[DefeatedByNickname], [l2].[DefeatedBySquadId], [l2].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l2] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] LEFT JOIN ( SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], N'Gear' AS [Discriminator] @@ -11910,8 +11910,8 @@ UNION ALL SELECT [o].[Nickname], [o].[SquadId], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName], [o].[HasSoulPatch], [o].[LeaderNickname], [o].[LeaderSquadId], [o].[Rank], N'Officer' AS [Discriminator] FROM [Officers] AS [o] ) AS [t0] ON [t].[DefeatedByNickname] = [t0].[Nickname] AND [t].[DefeatedBySquadId] = [t0].[SquadId] -LEFT JOIN [LocustHordes] AS [l] ON [t].[Name] = [l].[CommanderName] -LEFT JOIN [LocustHighCommands] AS [l0] ON [t].[HighCommandId] = [l0].[Id] +LEFT JOIN [LocustHordes] AS [l1] ON [t].[Name] = [l1].[CommanderName] +LEFT JOIN [LocustHighCommands] AS [l2] ON [t].[HighCommandId] = [l2].[Id] """); } @@ -13313,26 +13313,26 @@ public override async Task Set_operator_with_navigation_in_projection_groupby_ag SELECT [s].[Name], ( SELECT COALESCE(SUM(CAST(LEN([c].[Location]) AS int)), 0) FROM ( - SELECT [g0].[SquadId], [g0].[CityOfBirthName] - FROM [Gears] AS [g0] + SELECT [g2].[SquadId], [g2].[CityOfBirthName] + FROM [Gears] AS [g2] UNION ALL - SELECT [o0].[SquadId], [o0].[CityOfBirthName] - FROM [Officers] AS [o0] + SELECT [o2].[SquadId], [o2].[CityOfBirthName] + FROM [Officers] AS [o2] ) AS [t1] INNER JOIN [Squads] AS [s0] ON [t1].[SquadId] = [s0].[Id] INNER JOIN [Cities] AS [c] ON [t1].[CityOfBirthName] = [c].[Name] WHERE N'Marcus' IN ( - SELECT [g1].[Nickname] - FROM [Gears] AS [g1] + SELECT [g3].[Nickname] + FROM [Gears] AS [g3] UNION ALL - SELECT [o1].[Nickname] - FROM [Officers] AS [o1] + SELECT [o3].[Nickname] + FROM [Officers] AS [o3] UNION ALL - SELECT [g2].[Nickname] - FROM [Gears] AS [g2] + SELECT [g4].[Nickname] + FROM [Gears] AS [g4] UNION ALL - SELECT [o2].[Nickname] - FROM [Officers] AS [o2] + SELECT [o4].[Nickname] + FROM [Officers] AS [o4] ) AND ([s].[Name] = [s0].[Name] OR ([s].[Name] IS NULL AND [s0].[Name] IS NULL))) AS [SumOfLengths] FROM ( SELECT [g].[SquadId] @@ -13343,17 +13343,17 @@ FROM [Officers] AS [o] ) AS [t] INNER JOIN [Squads] AS [s] ON [t].[SquadId] = [s].[Id] WHERE N'Marcus' IN ( - SELECT [g3].[Nickname] - FROM [Gears] AS [g3] + SELECT [g0].[Nickname] + FROM [Gears] AS [g0] UNION ALL - SELECT [o3].[Nickname] - FROM [Officers] AS [o3] + SELECT [o0].[Nickname] + FROM [Officers] AS [o0] UNION ALL - SELECT [g4].[Nickname] - FROM [Gears] AS [g4] + SELECT [g1].[Nickname] + FROM [Gears] AS [g1] UNION ALL - SELECT [o4].[Nickname] - FROM [Officers] AS [o4] + SELECT [o1].[Nickname] + FROM [Officers] AS [o1] ) GROUP BY [s].[Name] """); @@ -13673,16 +13673,16 @@ public override async Task Derived_reference_is_skipped_when_base_type(bool asyn await base.Derived_reference_is_skipped_when_base_type(async); AssertSql( -""" -SELECT [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator], [l].[Id], [l].[IsOperational], [l].[Name] + """ +SELECT [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator], [l1].[Id], [l1].[IsOperational], [l1].[Name] FROM ( - SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] - FROM [LocustLeaders] AS [l0] + SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l1].[Name], [l1].[LocustHordeId], [l1].[ThreatLevel], [l1].[ThreatLevelByte], [l1].[ThreatLevelNullableByte], [l1].[DefeatedByNickname], [l1].[DefeatedBySquadId], [l1].[HighCommandId], N'LocustCommander' AS [Discriminator] - FROM [LocustCommanders] AS [l1] + SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator] + FROM [LocustCommanders] AS [l0] ) AS [t] -LEFT JOIN [LocustHighCommands] AS [l] ON [t].[HighCommandId] = [l].[Id] +LEFT JOIN [LocustHighCommands] AS [l1] ON [t].[HighCommandId] = [l1].[Id] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs index 04a28a60976..387490633ea 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs @@ -1193,17 +1193,17 @@ INNER JOIN ( SELECT [t].[Id], [t].[Name], [t].[Number], [t].[Slumber], [t].[IsGreen], [t].[IsBrown], [t].[Discriminator], [e0].[CompositeKeySkipSharedKey1], [e0].[CompositeKeySkipSharedKey2], [e0].[CompositeKeySkipSharedKey3] FROM [EntityCompositeKeyEntityRoot] AS [e0] INNER JOIN ( - SELECT [r0].[Id], [r0].[Name], NULL AS [Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityRoot' AS [Discriminator] - FROM [Roots] AS [r0] + SELECT [r].[Id], [r].[Name], NULL AS [Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityRoot' AS [Discriminator] + FROM [Roots] AS [r] UNION ALL - SELECT [b0].[Id], [b0].[Name], [b0].[Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityBranch' AS [Discriminator] - FROM [Branches] AS [b0] + SELECT [b].[Id], [b].[Name], [b].[Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityBranch' AS [Discriminator] + FROM [Branches] AS [b] UNION ALL - SELECT [l1].[Id], [l1].[Name], [l1].[Number], NULL AS [Slumber], [l1].[IsGreen], NULL AS [IsBrown], N'EntityLeaf' AS [Discriminator] - FROM [Leaves] AS [l1] + SELECT [l].[Id], [l].[Name], [l].[Number], NULL AS [Slumber], [l].[IsGreen], NULL AS [IsBrown], N'EntityLeaf' AS [Discriminator] + FROM [Leaves] AS [l] UNION ALL - SELECT [l2].[Id], [l2].[Name], NULL AS [Number], [l2].[Slumber], NULL AS [IsGreen], [l2].[IsBrown], N'EntityLeaf2' AS [Discriminator] - FROM [Leaf2s] AS [l2] + SELECT [l0].[Id], [l0].[Name], NULL AS [Number], [l0].[Slumber], NULL AS [IsGreen], [l0].[IsBrown], N'EntityLeaf2' AS [Discriminator] + FROM [Leaf2s] AS [l0] ) AS [t] ON [e0].[RootSkipSharedId] = [t].[Id] ) AS [t0] ON [e].[Key1] = [t0].[CompositeKeySkipSharedKey1] AND [e].[Key2] = [t0].[CompositeKeySkipSharedKey2] AND [e].[Key3] = [t0].[CompositeKeySkipSharedKey3] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3] @@ -1493,17 +1493,17 @@ ORDER BY [t].[Id] """ SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t].[Id], [t0].[RootSkipSharedId], [t0].[ThreeSkipSharedId] FROM ( - SELECT [r1].[Id] - FROM [Roots] AS [r1] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b1].[Id] - FROM [Branches] AS [b1] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l3].[Id] - FROM [Leaves] AS [l3] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l4].[Id] - FROM [Leaf2s] AS [l4] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [e].[RootSkipSharedId], [e].[ThreeSkipSharedId] @@ -1516,17 +1516,17 @@ FROM [EntityRootEntityThree] AS [e] """ SELECT [t1].[Id], [t1].[Name], [t].[Id], [t0].[RootSkipSharedId], [t0].[ThreeSkipSharedId], [t0].[Id] FROM ( - SELECT [r2].[Id] - FROM [Roots] AS [r2] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b2].[Id] - FROM [Branches] AS [b2] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l5].[Id] - FROM [Leaves] AS [l5] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l6].[Id] - FROM [Leaf2s] AS [l6] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e0].[Id], [e].[RootSkipSharedId], [e].[ThreeSkipSharedId] @@ -1569,17 +1569,17 @@ ORDER BY [t].[Id] """ SELECT [t0].[Key1], [t0].[Key2], [t0].[Key3], [t0].[Name], [t].[Id], [t0].[RootSkipSharedId], [t0].[CompositeKeySkipSharedKey1], [t0].[CompositeKeySkipSharedKey2], [t0].[CompositeKeySkipSharedKey3] FROM ( - SELECT [r1].[Id] - FROM [Roots] AS [r1] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b1].[Id] - FROM [Branches] AS [b1] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l3].[Id] - FROM [Leaves] AS [l3] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l4].[Id] - FROM [Leaf2s] AS [l4] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name], [e].[RootSkipSharedId], [e].[CompositeKeySkipSharedKey1], [e].[CompositeKeySkipSharedKey2], [e].[CompositeKeySkipSharedKey3] @@ -1592,17 +1592,17 @@ FROM [EntityCompositeKeyEntityRoot] AS [e] """ SELECT [t2].[Id], [t2].[CollectionInverseId], [t2].[Name], [t2].[ReferenceInverseId], [t].[Id], [t0].[RootSkipSharedId], [t0].[CompositeKeySkipSharedKey1], [t0].[CompositeKeySkipSharedKey2], [t0].[CompositeKeySkipSharedKey3], [t0].[Key1], [t0].[Key2], [t0].[Key3] FROM ( - SELECT [r2].[Id] - FROM [Roots] AS [r2] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b2].[Id] - FROM [Branches] AS [b2] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l5].[Id] - FROM [Leaves] AS [l5] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l6].[Id] - FROM [Leaf2s] AS [l6] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e0].[Key1], [e0].[Key2], [e0].[Key3], [e].[RootSkipSharedId], [e].[CompositeKeySkipSharedKey1], [e].[CompositeKeySkipSharedKey2], [e].[CompositeKeySkipSharedKey3] @@ -1852,11 +1852,11 @@ INNER JOIN ( SELECT [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen], [t].[Discriminator], [j1].[EntityOneId] FROM [JoinOneToBranch] AS [j1] INNER JOIN ( - SELECT [b0].[Id], [b0].[Name], [b0].[Number], NULL AS [IsGreen], N'EntityBranch' AS [Discriminator] - FROM [Branches] AS [b0] + SELECT [b].[Id], [b].[Name], [b].[Number], NULL AS [IsGreen], N'EntityBranch' AS [Discriminator] + FROM [Branches] AS [b] UNION ALL - SELECT [l0].[Id], [l0].[Name], [l0].[Number], [l0].[IsGreen], N'EntityLeaf' AS [Discriminator] - FROM [Leaves] AS [l0] + SELECT [l].[Id], [l].[Name], [l].[Number], [l].[IsGreen], N'EntityLeaf' AS [Discriminator] + FROM [Leaves] AS [l] ) AS [t] ON [j1].[EntityBranchId] = [t].[Id] WHERE [t].[Id] < 20 ) AS [t3] ON [t0].[Id] = [t3].[EntityOneId] @@ -2319,19 +2319,19 @@ public override async Task Select_many_over_skip_navigation_unidirectional(bool """ SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId] FROM ( - SELECT [u1].[Id] - FROM [UnidirectionalRoots] AS [u1] + SELECT [u].[Id] + FROM [UnidirectionalRoots] AS [u] UNION ALL - SELECT [u2].[Id] - FROM [UnidirectionalBranches] AS [u2] + SELECT [u0].[Id] + FROM [UnidirectionalBranches] AS [u0] UNION ALL - SELECT [u3].[Id] - FROM [UnidirectionalLeaves] AS [u3] + SELECT [u1].[Id] + FROM [UnidirectionalLeaves] AS [u1] ) AS [t] INNER JOIN ( - SELECT [u0].[Id], [u0].[CollectionInverseId], [u0].[Name], [u0].[ReferenceInverseId], [u].[UnidirectionalEntityRootId] - FROM [UnidirectionalEntityRootUnidirectionalEntityThree] AS [u] - INNER JOIN [UnidirectionalEntityThrees] AS [u0] ON [u].[ThreeSkipSharedId] = [u0].[Id] + SELECT [u3].[Id], [u3].[CollectionInverseId], [u3].[Name], [u3].[ReferenceInverseId], [u2].[UnidirectionalEntityRootId] + FROM [UnidirectionalEntityRootUnidirectionalEntityThree] AS [u2] + INNER JOIN [UnidirectionalEntityThrees] AS [u3] ON [u2].[ThreeSkipSharedId] = [u3].[Id] ) AS [t0] ON [t].[Id] = [t0].[UnidirectionalEntityRootId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs index 9a3c1714809..485fbd7988b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs @@ -1193,17 +1193,17 @@ INNER JOIN ( SELECT [e0].[RootSkipSharedId], [e0].[CompositeKeySkipSharedKey1], [e0].[CompositeKeySkipSharedKey2], [e0].[CompositeKeySkipSharedKey3], [t].[Id], [t].[Name], [t].[Number], [t].[Slumber], [t].[IsGreen], [t].[IsBrown], [t].[Discriminator] FROM [EntityCompositeKeyEntityRoot] AS [e0] INNER JOIN ( - SELECT [r0].[Id], [r0].[Name], NULL AS [Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityRoot' AS [Discriminator] - FROM [Roots] AS [r0] + SELECT [r].[Id], [r].[Name], NULL AS [Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityRoot' AS [Discriminator] + FROM [Roots] AS [r] UNION ALL - SELECT [b0].[Id], [b0].[Name], [b0].[Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityBranch' AS [Discriminator] - FROM [Branches] AS [b0] + SELECT [b].[Id], [b].[Name], [b].[Number], NULL AS [Slumber], NULL AS [IsGreen], NULL AS [IsBrown], N'EntityBranch' AS [Discriminator] + FROM [Branches] AS [b] UNION ALL - SELECT [l1].[Id], [l1].[Name], [l1].[Number], NULL AS [Slumber], [l1].[IsGreen], NULL AS [IsBrown], N'EntityLeaf' AS [Discriminator] - FROM [Leaves] AS [l1] + SELECT [l].[Id], [l].[Name], [l].[Number], NULL AS [Slumber], [l].[IsGreen], NULL AS [IsBrown], N'EntityLeaf' AS [Discriminator] + FROM [Leaves] AS [l] UNION ALL - SELECT [l2].[Id], [l2].[Name], NULL AS [Number], [l2].[Slumber], NULL AS [IsGreen], [l2].[IsBrown], N'EntityLeaf2' AS [Discriminator] - FROM [Leaf2s] AS [l2] + SELECT [l0].[Id], [l0].[Name], NULL AS [Number], [l0].[Slumber], NULL AS [IsGreen], [l0].[IsBrown], N'EntityLeaf2' AS [Discriminator] + FROM [Leaf2s] AS [l0] ) AS [t] ON [e0].[RootSkipSharedId] = [t].[Id] ) AS [t0] ON [e].[Key1] = [t0].[CompositeKeySkipSharedKey1] AND [e].[Key2] = [t0].[CompositeKeySkipSharedKey2] AND [e].[Key3] = [t0].[CompositeKeySkipSharedKey3] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3] @@ -1493,17 +1493,17 @@ ORDER BY [t].[Id] """ SELECT [t0].[RootSkipSharedId], [t0].[ThreeSkipSharedId], [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t].[Id] FROM ( - SELECT [r1].[Id] - FROM [Roots] AS [r1] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b1].[Id] - FROM [Branches] AS [b1] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l3].[Id] - FROM [Leaves] AS [l3] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l4].[Id] - FROM [Leaf2s] AS [l4] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e].[RootSkipSharedId], [e].[ThreeSkipSharedId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId] @@ -1516,17 +1516,17 @@ FROM [EntityRootEntityThree] AS [e] """ SELECT [t1].[OneId], [t1].[ThreeId], [t1].[Payload], [t1].[Id], [t1].[Name], [t].[Id], [t0].[RootSkipSharedId], [t0].[ThreeSkipSharedId], [t0].[Id] FROM ( - SELECT [r2].[Id] - FROM [Roots] AS [r2] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b2].[Id] - FROM [Branches] AS [b2] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l5].[Id] - FROM [Leaves] AS [l5] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l6].[Id] - FROM [Leaf2s] AS [l6] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e].[RootSkipSharedId], [e].[ThreeSkipSharedId], [e0].[Id] @@ -1569,17 +1569,17 @@ ORDER BY [t].[Id] """ SELECT [t0].[RootSkipSharedId], [t0].[CompositeKeySkipSharedKey1], [t0].[CompositeKeySkipSharedKey2], [t0].[CompositeKeySkipSharedKey3], [t0].[Key1], [t0].[Key2], [t0].[Key3], [t0].[Name], [t].[Id] FROM ( - SELECT [r1].[Id] - FROM [Roots] AS [r1] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b1].[Id] - FROM [Branches] AS [b1] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l3].[Id] - FROM [Leaves] AS [l3] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l4].[Id] - FROM [Leaf2s] AS [l4] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e].[RootSkipSharedId], [e].[CompositeKeySkipSharedKey1], [e].[CompositeKeySkipSharedKey2], [e].[CompositeKeySkipSharedKey3], [e0].[Key1], [e0].[Key2], [e0].[Key3], [e0].[Name] @@ -1592,17 +1592,17 @@ FROM [EntityCompositeKeyEntityRoot] AS [e] """ SELECT [t2].[Id], [t2].[CompositeId1], [t2].[CompositeId2], [t2].[CompositeId3], [t2].[ThreeId], [t2].[Id0], [t2].[CollectionInverseId], [t2].[Name], [t2].[ReferenceInverseId], [t].[Id], [t0].[RootSkipSharedId], [t0].[CompositeKeySkipSharedKey1], [t0].[CompositeKeySkipSharedKey2], [t0].[CompositeKeySkipSharedKey3], [t0].[Key1], [t0].[Key2], [t0].[Key3] FROM ( - SELECT [r2].[Id] - FROM [Roots] AS [r2] + SELECT [r].[Id] + FROM [Roots] AS [r] UNION ALL - SELECT [b2].[Id] - FROM [Branches] AS [b2] + SELECT [b].[Id] + FROM [Branches] AS [b] UNION ALL - SELECT [l5].[Id] - FROM [Leaves] AS [l5] + SELECT [l].[Id] + FROM [Leaves] AS [l] UNION ALL - SELECT [l6].[Id] - FROM [Leaf2s] AS [l6] + SELECT [l0].[Id] + FROM [Leaf2s] AS [l0] ) AS [t] INNER JOIN ( SELECT [e].[RootSkipSharedId], [e].[CompositeKeySkipSharedKey1], [e].[CompositeKeySkipSharedKey2], [e].[CompositeKeySkipSharedKey3], [e0].[Key1], [e0].[Key2], [e0].[Key3] @@ -1852,11 +1852,11 @@ INNER JOIN ( SELECT [j1].[EntityBranchId], [j1].[EntityOneId], [t].[Id], [t].[Name], [t].[Number], [t].[IsGreen], [t].[Discriminator] FROM [JoinOneToBranch] AS [j1] INNER JOIN ( - SELECT [b0].[Id], [b0].[Name], [b0].[Number], NULL AS [IsGreen], N'EntityBranch' AS [Discriminator] - FROM [Branches] AS [b0] + SELECT [b].[Id], [b].[Name], [b].[Number], NULL AS [IsGreen], N'EntityBranch' AS [Discriminator] + FROM [Branches] AS [b] UNION ALL - SELECT [l0].[Id], [l0].[Name], [l0].[Number], [l0].[IsGreen], N'EntityLeaf' AS [Discriminator] - FROM [Leaves] AS [l0] + SELECT [l].[Id], [l].[Name], [l].[Number], [l].[IsGreen], N'EntityLeaf' AS [Discriminator] + FROM [Leaves] AS [l] ) AS [t] ON [j1].[EntityBranchId] = [t].[Id] WHERE [t].[Id] < 20 ) AS [t3] ON [t0].[Id] = [t3].[EntityOneId] @@ -2320,19 +2320,19 @@ public override async Task Select_many_over_skip_navigation_unidirectional(bool """ SELECT [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId] FROM ( - SELECT [u1].[Id] - FROM [UnidirectionalRoots] AS [u1] + SELECT [u].[Id] + FROM [UnidirectionalRoots] AS [u] UNION ALL - SELECT [u2].[Id] - FROM [UnidirectionalBranches] AS [u2] + SELECT [u0].[Id] + FROM [UnidirectionalBranches] AS [u0] UNION ALL - SELECT [u3].[Id] - FROM [UnidirectionalLeaves] AS [u3] + SELECT [u1].[Id] + FROM [UnidirectionalLeaves] AS [u1] ) AS [t] INNER JOIN ( - SELECT [u0].[Id], [u0].[CollectionInverseId], [u0].[Name], [u0].[ReferenceInverseId], [u].[UnidirectionalEntityRootId] - FROM [UnidirectionalEntityRootUnidirectionalEntityThree] AS [u] - INNER JOIN [UnidirectionalEntityThrees] AS [u0] ON [u].[ThreeSkipSharedId] = [u0].[Id] + SELECT [u3].[Id], [u3].[CollectionInverseId], [u3].[Name], [u3].[ReferenceInverseId], [u2].[UnidirectionalEntityRootId] + FROM [UnidirectionalEntityRootUnidirectionalEntityThree] AS [u2] + INNER JOIN [UnidirectionalEntityThrees] AS [u3] ON [u2].[ThreeSkipSharedId] = [u3].[Id] ) AS [t0] ON [t].[Id] = [t0].[UnidirectionalEntityRootId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs index 22b7ce971c7..f2416b5cb37 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs @@ -25,30 +25,30 @@ public override void Changes_in_derived_related_entities_are_detected() AssertSql( """ -SELECT [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [t1].[BaseInheritanceRelationshipEntityId], [t1].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [t1].[Id0], [t1].[Name0], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [t1].[OwnedReferenceOnDerived_Id], [t1].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] +SELECT [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [t1].[BaseInheritanceRelationshipEntityId], [t1].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [t1].[Id0], [t1].[Name0], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [t1].[OwnedReferenceOnDerived_Id], [t1].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] FROM ( - SELECT TOP(2) [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [o].[Id] AS [Id0], [o].[Name] AS [Name0], [d].[Id] AS [Id1], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] + SELECT TOP(2) [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [o].[Id] AS [Id0], [o].[Name] AS [Name0], [d0].[Id] AS [Id1], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( - SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] - FROM [BaseEntities] AS [b0] + SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] - LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] + LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] WHERE [t].[Name] = N'Derived1(4)' ) AS [t1] LEFT JOIN [OwnedCollections] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t1].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t1].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( - SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d1] + SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], [d2].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d2] ) AS [t0] ON [t1].[Id] = [t0].[BaseParentId] -ORDER BY [t1].[Id], [t1].[BaseInheritanceRelationshipEntityId], [t1].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t1].[Id], [t1].[BaseInheritanceRelationshipEntityId], [t1].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -58,20 +58,20 @@ public override async Task Include_collection_without_inheritance(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [c].[Id], [c].[Name], [c].[ParentId] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [c].[Id], [c].[Name], [c].[ParentId] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN [CollectionsOnBase] AS [c] ON [t].[Id] = [c].[ParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -81,20 +81,20 @@ public override async Task Include_collection_without_inheritance_reverse(bool a AssertSql( """ -SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -104,21 +104,21 @@ public override async Task Include_collection_without_inheritance_with_filter(bo AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [c].[Id], [c].[Name], [c].[ParentId] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [c].[Id], [c].[Name], [c].[ParentId] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN [CollectionsOnBase] AS [c] ON [t].[Id] = [c].[ParentId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -128,21 +128,21 @@ public override async Task Include_collection_without_inheritance_with_filter_re AssertSql( """ -SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [c].[Name] <> N'Bar' OR [c].[Name] IS NULL -ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -152,18 +152,18 @@ public override async Task Include_collection_with_inheritance(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b0] @@ -171,7 +171,7 @@ UNION ALL SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], [d2].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] FROM [DerivedCollectionsOnBase] AS [d2] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -241,19 +241,19 @@ public override async Task Include_collection_with_inheritance_on_derived_revers AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentId], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d].[Id], [d].[Name], [d].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentId], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d0].[Id], [d0].[Name], [d0].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], [b].[ParentId], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseCollectionOnDerived' AS [Discriminator] FROM [BaseCollectionsOnDerived] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[ParentId], [d1].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] - FROM [DerivedCollectionsOnDerived] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[ParentId], [d].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] + FROM [DerivedCollectionsOnDerived] AS [d] ) AS [t] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[ParentId] = [d].[Id] -LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [d].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[ParentId] = [d0].[Id] +LEFT JOIN [OwnedReferences] AS [o] ON [d0].[Id] = [o].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [OwnedCollections] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d0].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -263,26 +263,26 @@ public override async Task Include_collection_with_inheritance_reverse(bool asyn AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t0].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t0].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -292,18 +292,18 @@ public override async Task Include_collection_with_inheritance_with_filter(bool AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b0] @@ -312,7 +312,7 @@ UNION ALL FROM [DerivedCollectionsOnBase] AS [d2] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -322,27 +322,27 @@ public override async Task Include_collection_with_inheritance_with_filter_rever AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t0].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t0].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -352,20 +352,20 @@ public override async Task Include_reference_without_inheritance(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [r].[Name], [r].[ParentId] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [r].[Name], [r].[ParentId] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [ReferencesOnBase] AS [r] ON [t].[Id] = [r].[ParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -423,20 +423,20 @@ public override async Task Include_reference_without_inheritance_reverse(bool as AssertSql( """ -SELECT [r].[Id], [r].[Name], [r].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [r].[Id], [r].[Name], [r].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [ReferencesOnBase] AS [r] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [r].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [r].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [r].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -446,21 +446,21 @@ public override async Task Include_reference_without_inheritance_with_filter(boo AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [r].[Name], [r].[ParentId] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [r].[Name], [r].[ParentId] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [ReferencesOnBase] AS [r] ON [t].[Id] = [r].[ParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [r].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -470,21 +470,21 @@ public override async Task Include_reference_without_inheritance_with_filter_rev AssertSql( """ -SELECT [r].[Id], [r].[Name], [r].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [r].[Id], [r].[Name], [r].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [ReferencesOnBase] AS [r] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [r].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [r].[Name] <> N'Bar' OR [r].[Name] IS NULL -ORDER BY [r].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [r].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -494,26 +494,26 @@ public override async Task Include_reference_with_inheritance(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d2] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -523,19 +523,19 @@ public override async Task Include_reference_with_inheritance_on_derived1(bool a AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -545,19 +545,19 @@ public override async Task Include_reference_with_inheritance_on_derived2(bool a AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseReferenceOnDerived' AS [Discriminator] FROM [BaseReferencesOnDerived] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] - FROM [DerivedReferencesOnDerived] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] + FROM [DerivedReferencesOnDerived] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -583,19 +583,19 @@ public override async Task Include_reference_with_inheritance_on_derived_reverse AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d].[Id], [d].[Name], [d].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d0].[Id], [d0].[Name], [d0].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseReferenceOnDerived' AS [Discriminator] FROM [BaseReferencesOnDerived] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] - FROM [DerivedReferencesOnDerived] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] + FROM [DerivedReferencesOnDerived] AS [d] ) AS [t] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[BaseParentId] = [d].[Id] -LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [d].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[BaseParentId] = [d0].[Id] +LEFT JOIN [OwnedReferences] AS [o] ON [d0].[Id] = [o].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [OwnedCollections] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d0].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -605,20 +605,20 @@ public override async Task Include_reference_with_inheritance_on_derived_with_fi AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [d].[Name] <> N'Bar' OR [d].[Name] IS NULL -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -628,20 +628,20 @@ public override async Task Include_reference_with_inheritance_on_derived_with_fi AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseReferenceOnDerived' AS [Discriminator] FROM [BaseReferencesOnDerived] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] - FROM [DerivedReferencesOnDerived] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] + FROM [DerivedReferencesOnDerived] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [d].[Name] <> N'Bar' OR [d].[Name] IS NULL -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -668,20 +668,20 @@ public override async Task Include_reference_with_inheritance_on_derived_with_fi AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d].[Id], [d].[Name], [d].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d0].[Id], [d0].[Name], [d0].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseReferenceOnDerived' AS [Discriminator] FROM [BaseReferencesOnDerived] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] - FROM [DerivedReferencesOnDerived] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedInheritanceRelationshipEntityId], N'DerivedReferenceOnDerived' AS [Discriminator] + FROM [DerivedReferencesOnDerived] AS [d] ) AS [t] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[BaseParentId] = [d].[Id] -LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[BaseParentId] = [d0].[Id] +LEFT JOIN [OwnedReferences] AS [o] ON [d0].[Id] = [o].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [OwnedCollections] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d0].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [d].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -691,26 +691,26 @@ public override async Task Include_reference_with_inheritance_reverse(bool async AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t0].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t0].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -720,27 +720,27 @@ public override async Task Include_reference_with_inheritance_with_filter(bool a AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d2] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -750,27 +750,27 @@ public override async Task Include_reference_with_inheritance_with_filter_revers AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t0].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t0].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -780,23 +780,23 @@ public override async Task Include_self_reference_with_inheritance(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [d].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [d].[Name], [d].[BaseId], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [o2].[Name], [o0].[Id], [o0].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [d0].[Name], [d0].[BaseId], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [o2].[Name], [o0].[Id], [o0].[Name], [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d3].[Id], [d3].[Name], [d3].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d3] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[BaseId] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[BaseId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] -LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] +LEFT JOIN [OwnedReferences] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o1] ON [t].[Id] = [o1].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] -LEFT JOIN [OwnedCollections] AS [o2] ON [d].[Id] = [o2].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [d].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [d].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [d2].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [OwnedCollections] AS [o2] ON [d0].[Id] = [o2].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d3] ON [d0].[Id] = [d3].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [d3].[DerivedInheritanceRelationshipEntityId] """); } @@ -806,23 +806,23 @@ public override async Task Include_self_reference_with_inheritance_reverse(bool AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[Name], [t].[BaseId], [t].[Discriminator], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [o2].[Name], [o0].[Id], [o0].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[Name], [t].[BaseId], [t].[Discriminator], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [o2].[Name], [o0].[Id], [o0].[Name], [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d3].[Id], [d3].[Name], [d3].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d3] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t] ON [d].[BaseId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o1] ON [d].[Id] = [o1].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [d].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o2] ON [t].[Id] = [o2].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [d2].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d3] ON [t].[Id] = [d3].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [o2].[BaseInheritanceRelationshipEntityId], [o2].[Id], [d3].[DerivedInheritanceRelationshipEntityId] """); } @@ -849,18 +849,18 @@ public override async Task Nested_include_with_inheritance_collection_collection AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t2].[Id], [t2].[BaseParentId], [t2].[Name], [t2].[DerivedProperty], [t2].[Discriminator], [t2].[Id0], [t2].[Name0], [t2].[ParentCollectionId], [t2].[ParentReferenceId], [t2].[Discriminator0] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [t2].[Id], [t2].[BaseParentId], [t2].[Name], [t2].[DerivedProperty], [t2].[Discriminator], [t2].[Id0], [t2].[Name0], [t2].[ParentCollectionId], [t2].[ParentReferenceId], [t2].[Discriminator0] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id] AS [Id0], [t1].[Name] AS [Name0], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] AS [Discriminator0] FROM ( @@ -878,7 +878,7 @@ UNION ALL FROM [NestedCollectionsDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentCollectionId] ) AS [t2] ON [t].[Id] = [t2].[BaseParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [t2].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [t2].[Id] """); } @@ -888,7 +888,7 @@ public override async Task Nested_include_with_inheritance_collection_collection AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -900,21 +900,21 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t1].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t1].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -924,18 +924,18 @@ public override async Task Nested_include_with_inheritance_collection_reference( AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t2].[Id], [t2].[BaseParentId], [t2].[Name], [t2].[DerivedProperty], [t2].[Discriminator], [t2].[Id0], [t2].[Name0], [t2].[ParentCollectionId], [t2].[ParentReferenceId], [t2].[Discriminator0] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [t2].[Id], [t2].[BaseParentId], [t2].[Name], [t2].[DerivedProperty], [t2].[Discriminator], [t2].[Id0], [t2].[Name0], [t2].[ParentCollectionId], [t2].[ParentReferenceId], [t2].[Discriminator0] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id] AS [Id0], [t1].[Name] AS [Name0], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] AS [Discriminator0] FROM ( @@ -953,7 +953,7 @@ UNION ALL FROM [NestedReferencesDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentCollectionId] ) AS [t2] ON [t].[Id] = [t2].[BaseParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [t2].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [t2].[Id] """); } @@ -963,7 +963,7 @@ public override async Task Nested_include_with_inheritance_collection_reference_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] FROM [NestedReferences] AS [n] @@ -975,21 +975,21 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], [d1].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t1].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t1].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -999,25 +999,25 @@ public override async Task Nested_include_with_inheritance_reference_collection( AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d2] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -1025,7 +1025,7 @@ UNION ALL SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] FROM [NestedCollectionsDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentReferenceId] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id] """); } @@ -1035,18 +1035,18 @@ public override async Task Nested_include_with_inheritance_reference_collection_ AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[ParentCollectionId], [t0].[ParentReferenceId], [t0].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[ParentCollectionId], [t0].[ParentReferenceId], [t0].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] LEFT JOIN ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -1054,7 +1054,7 @@ UNION ALL SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] FROM [NestedCollectionsDerived] AS [n0] ) AS [t0] ON [t].[Id] = [t0].[ParentReferenceId] -ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [d].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -1064,7 +1064,7 @@ public override async Task Nested_include_with_inheritance_reference_collection_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -1076,21 +1076,21 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t0] ON [t].[ParentReferenceId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t1].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t1].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -1100,20 +1100,20 @@ public override async Task Nested_include_with_inheritance_reference_reference(b AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d2] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] @@ -1123,10 +1123,10 @@ UNION ALL FROM [NestedReferencesDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentReferenceId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -1136,14 +1136,14 @@ public override async Task Nested_include_with_inheritance_reference_reference_o AssertSql( """ -SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Name], [t0].[ParentCollectionId], [t0].[ParentReferenceId], [t0].[Discriminator] +SELECT [d].[Id], [d].[Name], [d].[BaseId], [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d].[Id], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t].[BaseParentId], [t].[Name], [t].[Discriminator], [t0].[Name], [t0].[ParentCollectionId], [t0].[ParentReferenceId], [t0].[Discriminator] FROM [DerivedEntities] AS [d] LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] @@ -1154,8 +1154,8 @@ FROM [NestedReferencesDerived] AS [n0] ) AS [t0] ON [t].[Id] = [t0].[ParentReferenceId] LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] LEFT JOIN [OwnedCollections] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [d].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [d].[Id], [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [d].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +ORDER BY [d].[Id], [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId] """); } @@ -1165,7 +1165,7 @@ public override async Task Nested_include_with_inheritance_reference_reference_r AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] FROM [NestedReferences] AS [n] @@ -1177,21 +1177,21 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t0] ON [t].[ParentReferenceId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t1].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [t1].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d2].[DerivedInheritanceRelationshipEntityId] """); } @@ -1226,21 +1226,21 @@ public override async Task Include_on_derived_type_with_queryable_Cast(bool asyn AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [d1].[Id], [d1].[Name], [d1].[ParentId], [d1].[DerivedInheritanceRelationshipEntityId] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [o].[Id], [o].[Name], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name], [d2].[Id], [d2].[Name], [d2].[ParentId], [d2].[DerivedInheritanceRelationshipEntityId] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d2].[Id], [d2].[Name], [d2].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d2] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] LEFT JOIN [OwnedCollections] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [t].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] -LEFT JOIN [DerivedCollectionsOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [t].[Id] = [d1].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedCollectionsOnDerived] AS [d2] ON [t].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] WHERE [t].[Id] >= 4 -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id] """); } @@ -1250,27 +1250,27 @@ public override async Task Include_collection_with_inheritance_split(bool async) AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1281,11 +1281,11 @@ FROM [DerivedEntities] AS [d5] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1296,20 +1296,20 @@ FROM [DerivedEntities] AS [d6] """ SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] INNER JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId], [b5].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId], [d8].[Name], [d8].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d3] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] ORDER BY [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] """); @@ -1321,41 +1321,41 @@ public override async Task Include_collection_with_inheritance_reverse_split(boo AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d0] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b3].[Id], [b3].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d6] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t0].[Id] = [d2].[Id] @@ -1366,18 +1366,18 @@ FROM [DerivedEntities] AS [d7] """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b5].[Id], [b5].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t0].[Id] = [d2].[Id] @@ -1392,28 +1392,28 @@ public override async Task Include_collection_with_inheritance_with_filter_split AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id], [b2].[Name] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id], [d5].[Name] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1425,11 +1425,11 @@ WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id], [b3].[Name] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[Name] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1441,20 +1441,20 @@ WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL """ SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b4].[Id], [b4].[Name] - FROM [BaseEntities] AS [b4] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d7].[Id], [d7].[Name] - FROM [DerivedEntities] AS [d7] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] INNER JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId], [b5].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId], [d8].[Name], [d8].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d3] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL ORDER BY [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] @@ -1467,42 +1467,42 @@ public override async Task Include_collection_with_inheritance_with_filter_rever AssertSql( """ -SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[BaseParentId], [t].[Name], [t].[DerivedProperty], [t].[Discriminator], [t0].[Id], [t0].[Name], [t0].[BaseId], [t0].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d0] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t0].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t0].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t0].[Id] = [d1].[Id] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b3].[Id], [b3].[BaseParentId], [b3].[Name] - FROM [BaseCollectionsOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId], [b].[Name] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId], [d6].[Name] - FROM [DerivedCollectionsOnBase] AS [d6] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t0].[Id] = [d2].[Id] @@ -1514,18 +1514,18 @@ WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b5].[Id], [b5].[BaseParentId], [b5].[Name] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b].[Id], [b].[BaseParentId], [b].[Name] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId], [d8].[Name] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t0] ON [t].[BaseParentId] = [t0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t0].[Id] = [d2].[Id] @@ -1541,27 +1541,27 @@ public override async Task Include_collection_without_inheritance_split(bool asy AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b1].[Id] - FROM [BaseEntities] AS [b1] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d4].[Id] - FROM [DerivedEntities] AS [d4] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1572,11 +1572,11 @@ FROM [DerivedEntities] AS [d4] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1587,11 +1587,11 @@ FROM [DerivedEntities] AS [d5] """ SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1606,29 +1606,29 @@ public override async Task Include_collection_without_inheritance_reverse_split( AssertSql( """ -SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [c].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( - SELECT [b1].[Id] - FROM [BaseEntities] AS [b1] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d4].[Id] - FROM [DerivedEntities] AS [d4] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1640,11 +1640,11 @@ FROM [DerivedEntities] AS [d4] SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [c].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1659,28 +1659,28 @@ public override async Task Include_collection_without_inheritance_with_filter_sp AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b1].[Id], [b1].[Name] - FROM [BaseEntities] AS [b1] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d4].[Id], [d4].[Name] - FROM [DerivedEntities] AS [d4] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1692,11 +1692,11 @@ WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id], [b2].[Name] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id], [d5].[Name] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1708,11 +1708,11 @@ WHERE [t].[Name] <> N'Bar' OR [t].[Name] IS NULL """ SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id], [b3].[Name] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id], [b].[Name] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[Name] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id], [d].[Name] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1728,30 +1728,30 @@ public override async Task Include_collection_without_inheritance_with_filter_re AssertSql( """ -SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [c].[Id], [c].[Name], [c].[ParentId], [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] WHERE [c].[Name] <> N'Bar' OR [c].[Name] IS NULL -ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +ORDER BY [c].[Id], [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [c].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( - SELECT [b1].[Id] - FROM [BaseEntities] AS [b1] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d4].[Id] - FROM [DerivedEntities] AS [d4] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1764,11 +1764,11 @@ WHERE [c].[Name] <> N'Bar' OR [c].[Name] IS NULL SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [c].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM [CollectionsOnBase] AS [c] LEFT JOIN ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] ON [c].[ParentId] = [t].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -1811,11 +1811,11 @@ FROM [DerivedEntities] AS [d] FROM [DerivedEntities] AS [d] LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] INNER JOIN ( - SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b0] + SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d3] + SELECT [d2].[Id], [d2].[BaseParentId], [d2].[Name], [d2].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d2] ) AS [t] ON [d].[Id] = [t].[BaseParentId] ORDER BY [d].[Id], [o0].[BaseInheritanceRelationshipEntityId] """); @@ -1853,11 +1853,11 @@ FROM [DerivedEntities] AS [d] FROM [DerivedEntities] AS [d] LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] INNER JOIN ( - SELECT [b0].[Id], [b0].[Name], [b0].[ParentId], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseCollectionOnDerived' AS [Discriminator] - FROM [BaseCollectionsOnDerived] AS [b0] + SELECT [b].[Id], [b].[Name], [b].[ParentId], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseCollectionOnDerived' AS [Discriminator] + FROM [BaseCollectionsOnDerived] AS [b] UNION ALL - SELECT [d3].[Id], [d3].[Name], [d3].[ParentId], [d3].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] - FROM [DerivedCollectionsOnDerived] AS [d3] + SELECT [d2].[Id], [d2].[Name], [d2].[ParentId], [d2].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] + FROM [DerivedCollectionsOnDerived] AS [d2] ) AS [t] ON [d].[Id] = [t].[ParentId] ORDER BY [d].[Id], [o0].[BaseInheritanceRelationshipEntityId] """); @@ -1906,27 +1906,27 @@ public override async Task Include_collection_with_inheritance_on_derived_revers AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentId], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d].[Id], [d].[Name], [d].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentId], [t].[DerivedInheritanceRelationshipEntityId], [t].[Discriminator], [d0].[Id], [d0].[Name], [d0].[BaseId], [o].[BaseInheritanceRelationshipEntityId], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], [b].[ParentId], NULL AS [DerivedInheritanceRelationshipEntityId], N'BaseCollectionOnDerived' AS [Discriminator] FROM [BaseCollectionsOnDerived] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[ParentId], [d0].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] - FROM [DerivedCollectionsOnDerived] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[ParentId], [d].[DerivedInheritanceRelationshipEntityId], N'DerivedCollectionOnDerived' AS [Discriminator] + FROM [DerivedCollectionsOnDerived] AS [d] ) AS [t] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[ParentId] = [d].[Id] -LEFT JOIN [OwnedReferences] AS [o] ON [d].[Id] = [o].[BaseInheritanceRelationshipEntityId] -ORDER BY [t].[Id], [d].[Id], [o].[BaseInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[ParentId] = [d0].[Id] +LEFT JOIN [OwnedReferences] AS [o] ON [d0].[Id] = [o].[BaseInheritanceRelationshipEntityId] +ORDER BY [t].[Id], [d0].[Id], [o].[BaseInheritanceRelationshipEntityId] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId] FROM ( - SELECT [b1].[Id], [b1].[ParentId] - FROM [BaseCollectionsOnDerived] AS [b1] + SELECT [b].[Id], [b].[ParentId] + FROM [BaseCollectionsOnDerived] AS [b] UNION ALL - SELECT [d4].[Id], [d4].[ParentId] - FROM [DerivedCollectionsOnDerived] AS [d4] + SELECT [d].[Id], [d].[ParentId] + FROM [DerivedCollectionsOnDerived] AS [d] ) AS [t] LEFT JOIN [DerivedEntities] AS [d0] ON [t].[ParentId] = [d0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] @@ -1937,11 +1937,11 @@ FROM [DerivedCollectionsOnDerived] AS [d4] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId] FROM ( - SELECT [b2].[Id], [b2].[ParentId] - FROM [BaseCollectionsOnDerived] AS [b2] + SELECT [b].[Id], [b].[ParentId] + FROM [BaseCollectionsOnDerived] AS [b] UNION ALL - SELECT [d5].[Id], [d5].[ParentId] - FROM [DerivedCollectionsOnDerived] AS [d5] + SELECT [d].[Id], [d].[ParentId] + FROM [DerivedCollectionsOnDerived] AS [d] ) AS [t] LEFT JOIN [DerivedEntities] AS [d0] ON [t].[ParentId] = [d0].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [d0].[Id] = [o0].[BaseInheritanceRelationshipEntityId] @@ -1956,41 +1956,41 @@ public override async Task Nested_include_with_inheritance_reference_collection_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[BaseParentId], [d1].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d1] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] +ORDER BY [t].[Id], [t0].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b4].[Id], [b4].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b4] + SELECT [b0].[Id], [b0].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d7].[Id], [d7].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d7] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t].[Id] = [d2].[Id] @@ -2001,18 +2001,18 @@ FROM [DerivedReferencesOnBase] AS [d7] """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b5].[Id] - FROM [BaseEntities] AS [b5] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d8].[Id] - FROM [DerivedEntities] AS [d8] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b6].[Id], [b6].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b6] + SELECT [b0].[Id], [b0].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d9].[Id], [d9].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d9] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t].[Id] = [d2].[Id] @@ -2023,27 +2023,27 @@ FROM [DerivedReferencesOnBase] AS [d9] """ SELECT [t1].[Id], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator], [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [b7].[Id] - FROM [BaseEntities] AS [b7] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d10].[Id] - FROM [DerivedEntities] AS [d10] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN ( - SELECT [b8].[Id], [b8].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b8] + SELECT [b0].[Id], [b0].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b0] UNION ALL - SELECT [d11].[Id], [d11].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d11] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t].[Id] = [d2].[Id] INNER JOIN ( - SELECT [n1].[Id], [n1].[Name], [n1].[ParentCollectionId], [n1].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] - FROM [NestedCollections] AS [n1] + SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n2].[Id], [n2].[Name], [n2].[ParentCollectionId], [n2].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] - FROM [NestedCollectionsDerived] AS [n2] + SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentReferenceId] ORDER BY [t].[Id], [t0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] """); @@ -2072,11 +2072,11 @@ FROM [DerivedReferencesOnBase] AS [d0] SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [d].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId] FROM [DerivedEntities] AS [d] LEFT JOIN ( - SELECT [b1].[Id], [b1].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b1] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d4].[Id], [d4].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d4] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] INNER JOIN [OwnedCollections] AS [o1] ON [d].[Id] = [o1].[BaseInheritanceRelationshipEntityId] @@ -2087,11 +2087,11 @@ FROM [DerivedReferencesOnBase] AS [d4] SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [d].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId] FROM [DerivedEntities] AS [d] LEFT JOIN ( - SELECT [b2].[Id], [b2].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b2] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d5].[Id], [d5].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d5] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] INNER JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d2] ON [d].[Id] = [d2].[DerivedInheritanceRelationshipEntityId] @@ -2102,19 +2102,19 @@ FROM [DerivedReferencesOnBase] AS [d5] SELECT [t0].[Id], [t0].[Name], [t0].[ParentCollectionId], [t0].[ParentReferenceId], [t0].[Discriminator], [d].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId] FROM [DerivedEntities] AS [d] LEFT JOIN ( - SELECT [b3].[Id], [b3].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d6] + SELECT [d0].[Id], [d0].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d0] ) AS [t] ON [d].[Id] = [t].[BaseParentId] LEFT JOIN [OwnedReferences] AS [o0] ON [d].[Id] = [o0].[BaseInheritanceRelationshipEntityId] INNER JOIN ( - SELECT [n1].[Id], [n1].[Name], [n1].[ParentCollectionId], [n1].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] - FROM [NestedCollections] AS [n1] + SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n2].[Id], [n2].[Name], [n2].[ParentCollectionId], [n2].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] - FROM [NestedCollectionsDerived] AS [n2] + SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t0] ON [t].[Id] = [t0].[ParentReferenceId] ORDER BY [d].[Id], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId] """); @@ -2126,7 +2126,7 @@ public override async Task Nested_include_with_inheritance_reference_collection_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -2138,43 +2138,43 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], N'BaseReferenceOnBase' AS [Discriminator] FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], N'DerivedReferenceOnBase' AS [Discriminator] - FROM [DerivedReferencesOnBase] AS [d0] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], N'DerivedReferenceOnBase' AS [Discriminator] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t0] ON [t].[ParentReferenceId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n3].[Id], [n3].[ParentReferenceId] - FROM [NestedCollections] AS [n3] + SELECT [n].[Id], [n].[ParentReferenceId] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n4].[Id], [n4].[ParentReferenceId] - FROM [NestedCollectionsDerived] AS [n4] + SELECT [n0].[Id], [n0].[ParentReferenceId] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b3].[Id], [b3].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d6] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t0] ON [t].[ParentReferenceId] = [t0].[Id] LEFT JOIN ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2185,25 +2185,25 @@ FROM [DerivedEntities] AS [d7] """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n5].[Id], [n5].[ParentReferenceId] - FROM [NestedCollections] AS [n5] + SELECT [n].[Id], [n].[ParentReferenceId] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n6].[Id], [n6].[ParentReferenceId] - FROM [NestedCollectionsDerived] AS [n6] + SELECT [n0].[Id], [n0].[ParentReferenceId] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId] - FROM [BaseReferencesOnBase] AS [b5] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseReferencesOnBase] AS [b] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId] - FROM [DerivedReferencesOnBase] AS [d8] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedReferencesOnBase] AS [d] ) AS [t0] ON [t].[ParentReferenceId] = [t0].[Id] LEFT JOIN ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2218,27 +2218,27 @@ public override async Task Nested_include_with_inheritance_collection_reference_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2249,11 +2249,11 @@ FROM [DerivedEntities] AS [d5] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2264,29 +2264,29 @@ FROM [DerivedEntities] AS [d6] """ SELECT [t2].[Id], [t2].[BaseParentId], [t2].[Name], [t2].[DerivedProperty], [t2].[Discriminator], [t2].[Id0], [t2].[Name0], [t2].[ParentCollectionId], [t2].[ParentReferenceId], [t2].[Discriminator0] AS [Discriminator], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] INNER JOIN ( SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id] AS [Id0], [t1].[Name] AS [Name0], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator] AS [Discriminator0] FROM ( - SELECT [b5].[Id], [b5].[BaseParentId], [b5].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId], [d8].[Name], [d8].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d3] ) AS [t0] LEFT JOIN ( - SELECT [n1].[Id], [n1].[Name], [n1].[ParentCollectionId], [n1].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] - FROM [NestedReferences] AS [n1] + SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] + FROM [NestedReferences] AS [n] UNION ALL - SELECT [n2].[Id], [n2].[Name], [n2].[ParentCollectionId], [n2].[ParentReferenceId], N'NestedReferenceDerived' AS [Discriminator] - FROM [NestedReferencesDerived] AS [n2] + SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedReferenceDerived' AS [Discriminator] + FROM [NestedReferencesDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentCollectionId] ) AS [t2] ON [t].[Id] = [t2].[BaseParentId] ORDER BY [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] @@ -2299,7 +2299,7 @@ public override async Task Nested_include_with_inheritance_collection_reference_ AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedReferenceBase' AS [Discriminator] FROM [NestedReferences] AS [n] @@ -2311,43 +2311,43 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d0] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n3].[Id], [n3].[ParentCollectionId] - FROM [NestedReferences] AS [n3] + SELECT [n].[Id], [n].[ParentCollectionId] + FROM [NestedReferences] AS [n] UNION ALL - SELECT [n4].[Id], [n4].[ParentCollectionId] - FROM [NestedReferencesDerived] AS [n4] + SELECT [n0].[Id], [n0].[ParentCollectionId] + FROM [NestedReferencesDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b3].[Id], [b3].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d6] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2358,25 +2358,25 @@ FROM [DerivedEntities] AS [d7] """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n5].[Id], [n5].[ParentCollectionId] - FROM [NestedReferences] AS [n5] + SELECT [n].[Id], [n].[ParentCollectionId] + FROM [NestedReferences] AS [n] UNION ALL - SELECT [n6].[Id], [n6].[ParentCollectionId] - FROM [NestedReferencesDerived] AS [n6] + SELECT [n0].[Id], [n0].[ParentCollectionId] + FROM [NestedReferencesDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2391,27 +2391,27 @@ public override async Task Nested_include_with_inheritance_collection_collection AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2422,11 +2422,11 @@ FROM [DerivedEntities] AS [d5] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2437,20 +2437,20 @@ FROM [DerivedEntities] AS [d6] """ SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] INNER JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId], [b5].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId], [d8].[Name], [d8].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d3] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] ORDER BY [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id], [t0].[Id] """, @@ -2458,27 +2458,27 @@ FROM [DerivedCollectionsOnBase] AS [d8] """ SELECT [t1].[Id], [t1].[Name], [t1].[ParentCollectionId], [t1].[ParentReferenceId], [t1].[Discriminator], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id], [t0].[Id] FROM ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] INNER JOIN ( - SELECT [b7].[Id], [b7].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b7] + SELECT [b0].[Id], [b0].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d10].[Id], [d10].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d10] + SELECT [d3].[Id], [d3].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d3] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] INNER JOIN ( - SELECT [n1].[Id], [n1].[Name], [n1].[ParentCollectionId], [n1].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] - FROM [NestedCollections] AS [n1] + SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n2].[Id], [n2].[Name], [n2].[ParentCollectionId], [n2].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] - FROM [NestedCollectionsDerived] AS [n2] + SELECT [n0].[Id], [n0].[Name], [n0].[ParentCollectionId], [n0].[ParentReferenceId], N'NestedCollectionDerived' AS [Discriminator] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t1] ON [t0].[Id] = [t1].[ParentCollectionId] ORDER BY [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id], [t0].[Id] """); @@ -2490,7 +2490,7 @@ public override async Task Nested_include_with_inheritance_collection_collection AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[ParentCollectionId], [t].[ParentReferenceId], [t].[Discriminator], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t1].[Id], [t1].[Name], [t1].[BaseId], [t1].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id], [o].[Id], [o].[Name], [d1].[OwnedReferenceOnDerived_Id], [d1].[OwnedReferenceOnDerived_Name] FROM ( SELECT [n].[Id], [n].[Name], [n].[ParentCollectionId], [n].[ParentReferenceId], N'NestedCollectionBase' AS [Discriminator] FROM [NestedCollections] AS [n] @@ -2502,43 +2502,43 @@ LEFT JOIN ( SELECT [b].[Id], [b].[BaseParentId], [b].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d0] + SELECT [d].[Id], [d].[BaseParentId], [d].[Name], [d].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( SELECT [b0].[Id], [b0].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d1].[Id], [d1].[Name], [d1].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d1] + SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o] ON [t1].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t1].[Id] = [d].[Id] -ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +LEFT JOIN [DerivedEntities] AS [d1] ON [t1].[Id] = [d1].[Id] +ORDER BY [t].[Id], [t0].[Id], [t1].[Id], [o].[BaseInheritanceRelationshipEntityId], [d1].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n3].[Id], [n3].[ParentCollectionId] - FROM [NestedCollections] AS [n3] + SELECT [n].[Id], [n].[ParentCollectionId] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n4].[Id], [n4].[ParentCollectionId] - FROM [NestedCollectionsDerived] AS [n4] + SELECT [n0].[Id], [n0].[ParentCollectionId] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b3].[Id], [b3].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b3] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d6].[Id], [d6].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d6] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( - SELECT [b4].[Id] - FROM [BaseEntities] AS [b4] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2549,25 +2549,25 @@ FROM [DerivedEntities] AS [d7] """ SELECT [d3].[DerivedInheritanceRelationshipEntityId], [d3].[Id], [d3].[Name], [t].[Id], [t0].[Id], [t1].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d2].[Id] FROM ( - SELECT [n5].[Id], [n5].[ParentCollectionId] - FROM [NestedCollections] AS [n5] + SELECT [n].[Id], [n].[ParentCollectionId] + FROM [NestedCollections] AS [n] UNION ALL - SELECT [n6].[Id], [n6].[ParentCollectionId] - FROM [NestedCollectionsDerived] AS [n6] + SELECT [n0].[Id], [n0].[ParentCollectionId] + FROM [NestedCollectionsDerived] AS [n0] ) AS [t] LEFT JOIN ( - SELECT [b5].[Id], [b5].[BaseParentId] - FROM [BaseCollectionsOnBase] AS [b5] + SELECT [b].[Id], [b].[BaseParentId] + FROM [BaseCollectionsOnBase] AS [b] UNION ALL - SELECT [d8].[Id], [d8].[BaseParentId] - FROM [DerivedCollectionsOnBase] AS [d8] + SELECT [d].[Id], [d].[BaseParentId] + FROM [DerivedCollectionsOnBase] AS [d] ) AS [t0] ON [t].[ParentCollectionId] = [t0].[Id] LEFT JOIN ( - SELECT [b6].[Id] - FROM [BaseEntities] AS [b6] + SELECT [b0].[Id] + FROM [BaseEntities] AS [b0] UNION ALL - SELECT [d9].[Id] - FROM [DerivedEntities] AS [d9] + SELECT [d0].[Id] + FROM [DerivedEntities] AS [d0] ) AS [t1] ON [t0].[BaseParentId] = [t1].[Id] LEFT JOIN [OwnedReferences] AS [o0] ON [t1].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d2] ON [t1].[Id] = [d2].[Id] @@ -2619,18 +2619,18 @@ ORDER BY [t].[Id] """ SELECT [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator], [t].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d2].[Id] - FROM [DerivedEntities] AS [d2] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] INNER JOIN ( - SELECT [b3].[Id], [b3].[BaseParentId], [b3].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] - FROM [BaseCollectionsOnBase] AS [b3] + SELECT [b0].[Id], [b0].[BaseParentId], [b0].[Name], NULL AS [DerivedProperty], N'BaseCollectionOnBase' AS [Discriminator] + FROM [BaseCollectionsOnBase] AS [b0] UNION ALL - SELECT [d3].[Id], [d3].[BaseParentId], [d3].[Name], [d3].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] - FROM [DerivedCollectionsOnBase] AS [d3] + SELECT [d0].[Id], [d0].[BaseParentId], [d0].[Name], [d0].[DerivedProperty], N'DerivedCollectionOnBase' AS [Discriminator] + FROM [DerivedCollectionsOnBase] AS [d0] ) AS [t0] ON [t].[Id] = [t0].[BaseParentId] ORDER BY [t].[Id] """); @@ -2642,28 +2642,28 @@ public override async Task Include_on_derived_type_with_queryable_Cast_split(boo AssertSql( """ -SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o].[Id], [o].[Name], [d].[OwnedReferenceOnDerived_Id], [d].[OwnedReferenceOnDerived_Name] +SELECT [t].[Id], [t].[Name], [t].[BaseId], [t].[Discriminator], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o].[Id], [o].[Name], [d0].[OwnedReferenceOnDerived_Id], [d0].[OwnedReferenceOnDerived_Name] FROM ( SELECT [b].[Id], [b].[Name], NULL AS [BaseId], N'BaseInheritanceRelationshipEntity' AS [Discriminator] FROM [BaseEntities] AS [b] UNION ALL - SELECT [d0].[Id], [d0].[Name], [d0].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] - FROM [DerivedEntities] AS [d0] + SELECT [d].[Id], [d].[Name], [d].[BaseId], N'DerivedInheritanceRelationshipEntity' AS [Discriminator] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o] ON [t].[Id] = [o].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities] AS [d] ON [t].[Id] = [d].[Id] +LEFT JOIN [DerivedEntities] AS [d0] ON [t].[Id] = [d0].[Id] WHERE [t].[Id] >= 4 -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id] """, // """ SELECT [o1].[BaseInheritanceRelationshipEntityId], [o1].[Id], [o1].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b1].[Id] - FROM [BaseEntities] AS [b1] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d5].[Id] - FROM [DerivedEntities] AS [d5] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2675,11 +2675,11 @@ FROM [DerivedEntities] AS [d5] """ SELECT [d2].[DerivedInheritanceRelationshipEntityId], [d2].[Id], [d2].[Name], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b2].[Id] - FROM [BaseEntities] AS [b2] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d6].[Id] - FROM [DerivedEntities] AS [d6] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] @@ -2691,11 +2691,11 @@ FROM [DerivedEntities] AS [d6] """ SELECT [d3].[Id], [d3].[Name], [d3].[ParentId], [d3].[DerivedInheritanceRelationshipEntityId], [t].[Id], [o0].[BaseInheritanceRelationshipEntityId], [d1].[Id] FROM ( - SELECT [b3].[Id] - FROM [BaseEntities] AS [b3] + SELECT [b].[Id] + FROM [BaseEntities] AS [b] UNION ALL - SELECT [d7].[Id] - FROM [DerivedEntities] AS [d7] + SELECT [d].[Id] + FROM [DerivedEntities] AS [d] ) AS [t] LEFT JOIN [OwnedReferences] AS [o0] ON [t].[Id] = [o0].[BaseInheritanceRelationshipEntityId] LEFT JOIN [DerivedEntities] AS [d1] ON [t].[Id] = [d1].[Id] diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs index 23a529cd717..9e76e4dac11 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs @@ -231,12 +231,12 @@ SELECT 1 INNER JOIN "Orders" AS "o1" ON "o0"."OrderID" = "o1"."OrderID" WHERE "o1"."OrderID" IN ( SELECT ( - SELECT "o2"."OrderID" - FROM "Orders" AS "o2" - WHERE "o3"."CustomerID" = "o2"."CustomerID" OR ("o3"."CustomerID" IS NULL AND "o2"."CustomerID" IS NULL) + SELECT "o3"."OrderID" + FROM "Orders" AS "o3" + WHERE "o2"."CustomerID" = "o3"."CustomerID" OR ("o2"."CustomerID" IS NULL AND "o3"."CustomerID" IS NULL) LIMIT 1) - FROM "Orders" AS "o3" - GROUP BY "o3"."CustomerID" + FROM "Orders" AS "o2" + GROUP BY "o2"."CustomerID" HAVING COUNT(*) > 9 ) AND "o0"."OrderID" = "o"."OrderID" AND "o0"."ProductID" = "o"."ProductID") """); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs index 225ceb20e26..46ceb3da721 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs @@ -116,7 +116,7 @@ public override async Task Json_collection_Skip(bool async) WHERE ( SELECT "t0"."c" FROM ( - SELECT "t"."OwnedReferenceLeaf" ->> 'SomethingSomething' AS "c", "t"."key" AS "key0" + SELECT "t"."OwnedReferenceLeaf" ->> 'SomethingSomething' AS "c", "t"."key" FROM ( SELECT "o"."value" ->> 'OwnedReferenceLeaf' AS "OwnedReferenceLeaf", "o"."key" FROM json_each("j"."OwnedReferenceRoot", '$.OwnedCollectionBranch') AS "o" @@ -124,7 +124,7 @@ FROM json_each("j"."OwnedReferenceRoot", '$.OwnedCollectionBranch') AS "o" ORDER BY "t"."key" LIMIT -1 OFFSET 1 ) AS "t0" - ORDER BY "t0"."key0" + ORDER BY "t0"."key" LIMIT 1 OFFSET 0) = 'e1_r_c2_r' """); }