diff --git a/EFCore.sln.DotSettings b/EFCore.sln.DotSettings index 2c930b0705e..1b4974fd608 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 d4360b4a8d4..0caec315c1d 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs @@ -58,6 +58,14 @@ 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. @@ -111,19 +119,17 @@ 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; LambdaExpression? propertySelector; Expression? targetTablePropertySelector = null; - for (var i = 0; i < setters.Count; i++) + foreach (var setter in setters) { - (propertySelector, var valueSelector) = setters[i]; + (propertySelector, var valueSelector) = setter; var propertySelectorBody = RemapLambdaBody(source, propertySelector).UnwrapTypeConversion(out _); switch (_sqlTranslator.TranslateProjection(propertySelectorBody)) @@ -162,29 +168,22 @@ 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"); + var selectExpression = (SelectExpression)source.QueryExpression; + 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 dd4426e5b32..f90f1179844 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -1328,7 +1328,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); @@ -1657,7 +1657,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); @@ -1714,23 +1714,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; @@ -2086,8 +2083,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]; @@ -2128,14 +2125,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); @@ -2144,6 +2149,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), @@ -2162,12 +2172,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 @@ -2175,12 +2189,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 @@ -2192,12 +2210,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); } @@ -2209,10 +2234,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; } @@ -2229,10 +2254,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): { @@ -2247,13 +2272,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 @@ -2284,11 +2308,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) { @@ -2296,11 +2318,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; } } @@ -2316,7 +2338,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. @@ -2327,7 +2349,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; @@ -2342,16 +2364,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. @@ -2374,7 +2396,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: @@ -2393,7 +2415,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. @@ -2416,7 +2439,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 21f98780b5f..146386f8d8c 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 setOperationAlias = _sqlAliasManager.GenerateTableAlias("union"); 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 fabc74a8fe3..29380a58d02 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])); @@ -363,14 +349,12 @@ _projectionMapping[new ProjectionMember()] = var tableAlias = _sqlAliasManager.GenerateTableAlias("table"); 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) @@ -379,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); @@ -417,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())); @@ -441,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)); } } @@ -476,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(); @@ -503,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; @@ -524,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(); @@ -578,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(); @@ -606,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, @@ -631,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); @@ -663,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()); @@ -677,7 +654,7 @@ private void AddJsonNavigationBindings( IEntityType entityType, StructuralTypeProjectionExpression projection, Dictionary propertyExpressions, - TableReferenceExpression tableReferenceExpression) + string tableAlias) { foreach (var ownedJsonNavigation in GetAllNavigationsInHierarchy(entityType) .Where( @@ -695,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); @@ -1439,10 +1416,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 @@ -1464,11 +1437,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( @@ -1488,7 +1457,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) { @@ -1501,7 +1469,8 @@ static Expression RemoveConvert(Expression expression) { innerOrderingExpressions.Add( new OrderingExpression( - subquery.GenerateOuterColumn(collectionJoinedTableReference, ordering.Expression), + subquery.GenerateOuterColumn( + collectionJoinedInnerTable.GetRequiredAlias(), ordering.Expression), ordering.IsAscending)); } } @@ -1515,10 +1484,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) @@ -1571,7 +1537,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) { @@ -1584,7 +1549,8 @@ static Expression RemoveConvert(Expression expression) { innerOrderingExpressions.Add( new OrderingExpression( - subquery.GenerateOuterColumn(collectionJoinedTableReference, ordering.Expression), + subquery.GenerateOuterColumn( + collectionJoinedInnerTable.GetRequiredAlias(), ordering.Expression), ordering.IsAscending)); } } @@ -1598,10 +1564,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) @@ -1702,11 +1665,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 { @@ -1716,14 +1678,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)); } @@ -1732,8 +1694,8 @@ void GetOrderingsFromInnerTable( orderings.Add( new OrderingExpression( joinedSubquery.GenerateOuterColumn( - tableReferenceExpression, - rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableReference, ordering.Expression)), + tableAlias, + rowNumberSubquery.GenerateOuterColumn(rowNumberSubqueryTableAlias, ordering.Expression)), ordering.IsAscending)); } } @@ -1744,7 +1706,7 @@ void GetOrderingsFromInnerTable( { orderings.Add( new OrderingExpression( - collectionSelectExpression.GenerateOuterColumn(tableReferenceExpression, ordering.Expression), + collectionSelectExpression.GenerateOuterColumn(tableAlias, ordering.Expression), ordering.IsAscending)); } } @@ -2109,10 +2071,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) @@ -2128,9 +2091,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(); @@ -2147,10 +2111,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]; @@ -2219,13 +2184,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); } @@ -2276,13 +2240,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); } @@ -2503,8 +2466,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, @@ -2520,7 +2482,6 @@ private void ApplySetOperation( _groupBy.Clear(); _orderings.Clear(); _tables.Clear(); - _tableReferences.Clear(); select1._projectionMapping = new Dictionary(_projectionMapping); _projectionMapping.Clear(); select1._identifier.AddRange(_identifier); @@ -2532,15 +2493,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(); @@ -2585,7 +2537,6 @@ private void ApplySetOperation( } var setOperationAlias = _sqlAliasManager.GenerateTableAlias(setOperationType.ToString()); - var tableReferenceExpression = new TableReferenceExpression(this, setOperationAlias); foreach (var (projectionMember, expression1, expression2) in select1._projectionMapping.Join( select2._projectionMapping, @@ -2612,7 +2563,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)) @@ -2669,7 +2620,6 @@ private void ApplySetOperation( _ => throw new InvalidOperationException(CoreStrings.InvalidSwitch(nameof(setOperationType), setOperationType)) }; _tables.Add(setExpression); - _tableReferences.Add(tableReferenceExpression); select1._projectionMapping.Clear(); select2._projectionMapping.Clear(); @@ -2735,7 +2685,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) { @@ -2796,7 +2746,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 @@ -2806,7 +2756,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( @@ -2877,13 +2827,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) @@ -2952,7 +2898,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 @@ -2964,11 +2911,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(); @@ -2982,7 +2927,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); @@ -3001,12 +2946,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 @@ -3021,20 +2964,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); } @@ -3046,7 +2988,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 { @@ -3057,17 +2999,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)); } } } @@ -3084,7 +3024,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); } @@ -3095,12 +3035,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); } @@ -3111,23 +3049,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); } @@ -3142,17 +3078,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)); } } @@ -3168,7 +3102,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); } @@ -3180,22 +3114,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; @@ -3242,7 +3174,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"); @@ -3254,6 +3186,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, @@ -3417,9 +3380,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) @@ -3548,9 +3510,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) { @@ -3559,7 +3519,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); } @@ -3611,7 +3571,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 @@ -3750,7 +3710,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 @@ -3759,7 +3719,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 }; @@ -3778,7 +3738,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) @@ -3786,19 +3746,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; } } @@ -3977,8 +3937,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr _sqlAliasManager.GenerateTableAlias(_tables is [{ Alias: string singleTableAlias }] ? singleTableAlias : "subquery"); 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, @@ -3988,7 +3947,6 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr _mutable = false }; _tables.Clear(); - _tableReferences.Clear(); _groupBy.Clear(); _orderings.Clear(); IsDistinct = false; @@ -4004,16 +3962,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); @@ -4023,7 +3972,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; } @@ -4044,7 +3993,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) { @@ -4053,7 +4002,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; @@ -4076,7 +4025,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) { @@ -4086,7 +4035,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; } @@ -4098,7 +4047,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); } } @@ -4109,7 +4058,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)); @@ -4122,7 +4071,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)); @@ -4142,7 +4091,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr { _orderings.Add( ordering.Update( - subquery.GenerateOuterColumn(subqueryTableReferenceExpression, orderingExpression))); + subquery.GenerateOuterColumn(subqueryAlias, orderingExpression))); } else { @@ -4157,15 +4106,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) { @@ -4183,7 +4124,7 @@ private SqlRemappingVisitor PushdownIntoSubqueryInternal(bool liftOrderings = tr StructuralTypeProjectionExpression LiftEntityProjectionFromSubquery( StructuralTypeProjectionExpression projection, - TableReferenceExpression subqueryTableReference) + string subqueryAlias) { var propertyExpressions = new Dictionary(); @@ -4203,7 +4144,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; } @@ -4219,11 +4160,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); @@ -4240,7 +4181,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); @@ -4261,7 +4202,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(); @@ -4269,7 +4210,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; } @@ -4331,17 +4272,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 @@ -4360,6 +4296,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) { @@ -4368,16 +4309,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)) @@ -4388,7 +4319,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, @@ -4400,28 +4331,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; } @@ -4455,12 +4380,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--) { @@ -4476,6 +4401,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) @@ -4521,49 +4451,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( @@ -4629,13 +4542,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 { @@ -4667,57 +4573,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) { @@ -4736,11 +4641,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; @@ -4802,23 +4702,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; @@ -4878,9 +4776,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, @@ -4901,39 +4798,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; } @@ -5017,10 +4881,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(), @@ -5036,15 +4898,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/Query/EntitySplittingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/EntitySplittingQuerySqlServerTest.cs index 882dad886a0..9f45cae33f1 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] """); } @@ -683,7 +683,7 @@ public override async Task Tpc_entity_owning_a_split_collection_on_base(bool asy AssertSql( """ -SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [s].[BaseEntityId], [s].[Id], [s].[OwnedIntValue1], [s].[OwnedIntValue2], [s].[OwnedIntValue3], [s].[OwnedIntValue4], [s].[OwnedStringValue1], [s].[OwnedStringValue2], [s].[OwnedStringValue3], [s].[OwnedStringValue4] +SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [s0].[BaseEntityId], [s0].[Id], [s0].[OwnedIntValue1], [s0].[OwnedIntValue2], [s0].[OwnedIntValue3], [s0].[OwnedIntValue4], [s0].[OwnedStringValue1], [s0].[OwnedStringValue2], [s0].[OwnedStringValue3], [s0].[OwnedStringValue4] FROM ( SELECT [b].[Id], [b].[BaseValue], NULL AS [MiddleValue], NULL AS [SiblingValue], NULL AS [LeafValue], N'BaseEntity' AS [Discriminator] FROM [BaseEntity] AS [b] @@ -691,8 +691,8 @@ UNION ALL SELECT [m].[Id], [m].[BaseValue], [m].[MiddleValue], NULL AS [SiblingValue], NULL AS [LeafValue], N'MiddleEntity' AS [Discriminator] FROM [MiddleEntity] AS [m] UNION ALL - SELECT [s0].[Id], [s0].[BaseValue], NULL AS [MiddleValue], [s0].[SiblingValue], NULL AS [LeafValue], N'SiblingEntity' AS [Discriminator] - FROM [SiblingEntity] AS [s0] + SELECT [s].[Id], [s].[BaseValue], NULL AS [MiddleValue], [s].[SiblingValue], NULL AS [LeafValue], N'SiblingEntity' AS [Discriminator] + FROM [SiblingEntity] AS [s] UNION ALL SELECT [l].[Id], [l].[BaseValue], [l].[MiddleValue], NULL AS [SiblingValue], [l].[LeafValue], N'LeafEntity' AS [Discriminator] FROM [LeafEntity] AS [l] @@ -702,8 +702,8 @@ LEFT JOIN ( FROM [OwnedReferencePart1] AS [o] INNER JOIN [OwnedReferencePart4] AS [o0] ON [o].[BaseEntityId] = [o0].[BaseEntityId] AND [o].[Id] = [o0].[Id] INNER JOIN [OwnedReferencePart3] AS [o1] ON [o].[BaseEntityId] = [o1].[BaseEntityId] AND [o].[Id] = [o1].[Id] -) AS [s] ON [t].[Id] = [s].[BaseEntityId] -ORDER BY [t].[Id], [s].[BaseEntityId] +) AS [s0] ON [t].[Id] = [s0].[BaseEntityId] +ORDER BY [t].[Id], [s0].[BaseEntityId] """); } @@ -729,7 +729,7 @@ public override async Task Tpc_entity_owning_a_split_collection_on_middle(bool a AssertSql( """ -SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [s].[MiddleEntityId], [s].[Id], [s].[OwnedIntValue1], [s].[OwnedIntValue2], [s].[OwnedIntValue3], [s].[OwnedIntValue4], [s].[OwnedStringValue1], [s].[OwnedStringValue2], [s].[OwnedStringValue3], [s].[OwnedStringValue4] +SELECT [t].[Id], [t].[BaseValue], [t].[MiddleValue], [t].[SiblingValue], [t].[LeafValue], [t].[Discriminator], [s0].[MiddleEntityId], [s0].[Id], [s0].[OwnedIntValue1], [s0].[OwnedIntValue2], [s0].[OwnedIntValue3], [s0].[OwnedIntValue4], [s0].[OwnedStringValue1], [s0].[OwnedStringValue2], [s0].[OwnedStringValue3], [s0].[OwnedStringValue4] FROM ( SELECT [b].[Id], [b].[BaseValue], NULL AS [MiddleValue], NULL AS [SiblingValue], NULL AS [LeafValue], N'BaseEntity' AS [Discriminator] FROM [BaseEntity] AS [b] @@ -737,8 +737,8 @@ UNION ALL SELECT [m].[Id], [m].[BaseValue], [m].[MiddleValue], NULL AS [SiblingValue], NULL AS [LeafValue], N'MiddleEntity' AS [Discriminator] FROM [MiddleEntity] AS [m] UNION ALL - SELECT [s0].[Id], [s0].[BaseValue], NULL AS [MiddleValue], [s0].[SiblingValue], NULL AS [LeafValue], N'SiblingEntity' AS [Discriminator] - FROM [SiblingEntity] AS [s0] + SELECT [s].[Id], [s].[BaseValue], NULL AS [MiddleValue], [s].[SiblingValue], NULL AS [LeafValue], N'SiblingEntity' AS [Discriminator] + FROM [SiblingEntity] AS [s] UNION ALL SELECT [l].[Id], [l].[BaseValue], [l].[MiddleValue], NULL AS [SiblingValue], [l].[LeafValue], N'LeafEntity' AS [Discriminator] FROM [LeafEntity] AS [l] @@ -748,8 +748,8 @@ LEFT JOIN ( FROM [OwnedReferencePart1] AS [o] INNER JOIN [OwnedReferencePart4] AS [o0] ON [o].[MiddleEntityId] = [o0].[MiddleEntityId] AND [o].[Id] = [o0].[Id] INNER JOIN [OwnedReferencePart3] AS [o1] ON [o].[MiddleEntityId] = [o1].[MiddleEntityId] AND [o].[Id] = [o1].[Id] -) AS [s] ON [t].[Id] = [s].[MiddleEntityId] -ORDER BY [t].[Id], [s].[MiddleEntityId] +) AS [s0] ON [t].[Id] = [s0].[MiddleEntityId] +ORDER BY [t].[Id], [s0].[MiddleEntityId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index d06c2159e9e..82d43c66fe2 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 [s] ON [t2].[FullName] = [s].[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], [s].[IsAutomatic], [s].[Nickname] DESC, [s].[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 [s] ON [t2].[FullName] = [s].[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], [s].[IsAutomatic], [s].[Nickname] DESC, [s].[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 [s] ON [t2].[FullName] = [s].[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], [s].[Id] DESC, [s].[c], [s].[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], [s0].[Id], [s0].[Nickname] AS [Nickname0], [s0].[SquadId] AS [SquadId0], [s0].[Id0], [s0].[Name], [s0].[IsAutomatic], [s0].[Id1], [s0].[Nickname0] AS [Nickname00], [s0].[HasSoulPatch], [s0].[SquadId0] AS [SquadId00], [t3].[Rank], [s0].[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 [s0] ON [t3].[FullName] = [s0].[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 [s2] ON [t2].[FullName] = [s2].[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], [s1].[Rank], [s1].[Nickname], [s1].[SquadId], [s1].[IsAutomatic0], [s1].[Id], [s1].[Nickname0], [s1].[SquadId0], [s1].[Id0], [s1].[Id1], [s1].[Nickname00], [s1].[SquadId00], [s2].[IsAutomatic], [s2].[Nickname] DESC, [s2].[Id] @@ -6765,20 +6765,20 @@ public override async Task Null_semantics_on_nullable_bool_from_inner_join_subqu AssertSql( """ -SELECT [l0].[Id], [l0].[CapitalName], [l0].[Name], [l0].[ServerAddress], [l0].[CommanderName], [l0].[Eradicated] +SELECT [l2].[Id], [l2].[CapitalName], [l2].[Name], [l2].[ServerAddress], [l2].[CommanderName], [l2].[Eradicated] FROM ( - SELECT [l1].[Name] - FROM [LocustLeaders] AS [l1] + SELECT [l].[Name] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l2].[Name] - FROM [LocustCommanders] AS [l2] + 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' -) AS [l0] ON [t].[Name] = [l0].[CommanderName] -WHERE [l0].[Eradicated] <> CAST(1 AS bit) OR [l0].[Eradicated] IS NULL + SELECT [l1].[Id], [l1].[CapitalName], [l1].[Name], [l1].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated] + FROM [LocustHordes] AS [l1] + WHERE [l1].[Name] = N'Swarm' +) AS [l2] ON [t].[Name] = [l2].[CommanderName] +WHERE [l2].[Eradicated] <> CAST(1 AS bit) OR [l2].[Eradicated] IS NULL """); } @@ -6788,20 +6788,20 @@ public override async Task Null_semantics_on_nullable_bool_from_left_join_subque AssertSql( """ -SELECT [l0].[Id], [l0].[CapitalName], [l0].[Name], [l0].[ServerAddress], [l0].[CommanderName], [l0].[Eradicated] +SELECT [l2].[Id], [l2].[CapitalName], [l2].[Name], [l2].[ServerAddress], [l2].[CommanderName], [l2].[Eradicated] FROM ( - SELECT [l1].[Name] - FROM [LocustLeaders] AS [l1] + SELECT [l].[Name] + FROM [LocustLeaders] AS [l] UNION ALL - SELECT [l2].[Name] - FROM [LocustCommanders] AS [l2] + 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' -) AS [l0] ON [t].[Name] = [l0].[CommanderName] -WHERE [l0].[Eradicated] <> CAST(1 AS bit) OR [l0].[Eradicated] IS NULL + SELECT [l1].[Id], [l1].[CapitalName], [l1].[Name], [l1].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated] + FROM [LocustHordes] AS [l1] + WHERE [l1].[Name] = N'Swarm' +) AS [l2] ON [t].[Name] = [l2].[CommanderName] +WHERE [l2].[Eradicated] <> CAST(1 AS bit) OR [l2].[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 [t0] INNER JOIN [Squads] AS [s0] ON [t0].[SquadId] = [s0].[Id] INNER JOIN [Cities] AS [c] ON [t0].[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/TPCInheritanceQuerySqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTestBase.cs index 709683c53e6..9f870ca1660 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCInheritanceQuerySqlServerTestBase.cs @@ -73,19 +73,19 @@ public override async Task Can_include_prey(bool async) AssertSql( """ -SELECT [e0].[Id], [e0].[CountryId], [e0].[Name], [e0].[Species], [e0].[EagleId], [e0].[IsFlightless], [e0].[Group], [t].[Id], [t].[CountryId], [t].[Name], [t].[Species], [t].[EagleId], [t].[IsFlightless], [t].[Group], [t].[FoundOn], [t].[Discriminator] +SELECT [e1].[Id], [e1].[CountryId], [e1].[Name], [e1].[Species], [e1].[EagleId], [e1].[IsFlightless], [e1].[Group], [t].[Id], [t].[CountryId], [t].[Name], [t].[Species], [t].[EagleId], [t].[IsFlightless], [t].[Group], [t].[FoundOn], [t].[Discriminator] FROM ( SELECT TOP(2) [e].[Id], [e].[CountryId], [e].[Name], [e].[Species], [e].[EagleId], [e].[IsFlightless], [e].[Group] FROM [Eagle] AS [e] -) AS [e0] +) AS [e1] LEFT JOIN ( - SELECT [e1].[Id], [e1].[CountryId], [e1].[Name], [e1].[Species], [e1].[EagleId], [e1].[IsFlightless], [e1].[Group], NULL AS [FoundOn], N'Eagle' AS [Discriminator] - FROM [Eagle] AS [e1] + SELECT [e0].[Id], [e0].[CountryId], [e0].[Name], [e0].[Species], [e0].[EagleId], [e0].[IsFlightless], [e0].[Group], NULL AS [FoundOn], N'Eagle' AS [Discriminator] + FROM [Eagle] AS [e0] UNION ALL SELECT [k].[Id], [k].[CountryId], [k].[Name], [k].[Species], [k].[EagleId], [k].[IsFlightless], NULL AS [Group], [k].[FoundOn], N'Kiwi' AS [Discriminator] FROM [Kiwi] AS [k] -) AS [t] ON [e0].[Id] = [t].[EagleId] -ORDER BY [e0].[Id] +) AS [t] ON [e1].[Id] = [t].[EagleId] +ORDER BY [e1].[Id] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs index 8d3e9d5addc..bafd2f6f29b 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 [s] ON [e].[Key1] = [s].[CompositeKeySkipSharedKey1] AND [e].[Key2] = [s].[CompositeKeySkipSharedKey2] AND [e].[Key3] = [s].[CompositeKeySkipSharedKey3] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3] @@ -1493,17 +1493,17 @@ ORDER BY [t].[Id] """ SELECT [s].[Id], [s].[CollectionInverseId], [s].[Name], [s].[ReferenceInverseId], [t].[Id], [s].[RootSkipSharedId], [s].[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 [s0].[Id], [s0].[Name], [t].[Id], [s].[RootSkipSharedId], [s].[ThreeSkipSharedId], [s].[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 [s].[Key1], [s].[Key2], [s].[Key3], [s].[Name], [t].[Id], [s].[RootSkipSharedId], [s].[CompositeKeySkipSharedKey1], [s].[CompositeKeySkipSharedKey2], [s].[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 [s1].[Id], [s1].[CollectionInverseId], [s1].[Name], [s1].[ReferenceInverseId], [t].[Id], [s].[RootSkipSharedId], [s].[CompositeKeySkipSharedKey1], [s].[CompositeKeySkipSharedKey2], [s].[CompositeKeySkipSharedKey3], [s].[Key1], [s].[Key2], [s].[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 [s2] ON [s].[Id] = [s2].[EntityOneId] @@ -2319,19 +2319,19 @@ public override async Task Select_many_over_skip_navigation_unidirectional(bool """ SELECT [s].[Id], [s].[CollectionInverseId], [s].[Name], [s].[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 [s] ON [t].[Id] = [s].[UnidirectionalEntityRootId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs index 751be6cdf8b..490ccaaf4ed 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 [s] ON [e].[Key1] = [s].[CompositeKeySkipSharedKey1] AND [e].[Key2] = [s].[CompositeKeySkipSharedKey2] AND [e].[Key3] = [s].[CompositeKeySkipSharedKey3] ORDER BY [e].[Key1], [e].[Key2], [e].[Key3] @@ -1493,17 +1493,17 @@ ORDER BY [t].[Id] """ SELECT [s].[RootSkipSharedId], [s].[ThreeSkipSharedId], [s].[Id], [s].[CollectionInverseId], [s].[Name], [s].[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 [s0].[OneId], [s0].[ThreeId], [s0].[Payload], [s0].[Id], [s0].[Name], [t].[Id], [s].[RootSkipSharedId], [s].[ThreeSkipSharedId], [s].[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 [s].[RootSkipSharedId], [s].[CompositeKeySkipSharedKey1], [s].[CompositeKeySkipSharedKey2], [s].[CompositeKeySkipSharedKey3], [s].[Key1], [s].[Key2], [s].[Key3], [s].[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 [s1].[Id], [s1].[CompositeId1], [s1].[CompositeId2], [s1].[CompositeId3], [s1].[ThreeId], [s1].[Id0], [s1].[CollectionInverseId], [s1].[Name], [s1].[ReferenceInverseId], [t].[Id], [s].[RootSkipSharedId], [s].[CompositeKeySkipSharedKey1], [s].[CompositeKeySkipSharedKey2], [s].[CompositeKeySkipSharedKey3], [s].[Key1], [s].[Key2], [s].[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 [s2] ON [s].[Id] = [s2].[EntityOneId] @@ -2320,19 +2320,19 @@ public override async Task Select_many_over_skip_navigation_unidirectional(bool """ SELECT [s].[Id], [s].[CollectionInverseId], [s].[Name], [s].[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 [s] ON [t].[Id] = [s].[UnidirectionalEntityRootId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCRelationshipsQuerySqlServerTest.cs index 12f3699e98e..332ddfbd254 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 [s].[Id], [s].[Name], [s].[BaseId], [s].[Discriminator], [s].[BaseInheritanceRelationshipEntityId], [s].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [s].[Id0], [s].[Name0], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [d0].[Name], [s].[OwnedReferenceOnDerived_Id], [s].[OwnedReferenceOnDerived_Name], [t0].[Id], [t0].[BaseParentId], [t0].[Name], [t0].[DerivedProperty], [t0].[Discriminator] +SELECT [s].[Id], [s].[Name], [s].[BaseId], [s].[Discriminator], [s].[BaseInheritanceRelationshipEntityId], [s].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [o0].[Name], [s].[Id0], [s].[Name0], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [d1].[Name], [s].[OwnedReferenceOnDerived_Id], [s].[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 [s] LEFT JOIN [OwnedCollections] AS [o0] ON [s].[Id] = [o0].[BaseInheritanceRelationshipEntityId] -LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d0] ON [s].[Id] = [d0].[DerivedInheritanceRelationshipEntityId] +LEFT JOIN [DerivedEntities_OwnedCollectionOnDerived] AS [d1] ON [s].[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 [s].[Id] = [t0].[BaseParentId] -ORDER BY [s].[Id], [s].[BaseInheritanceRelationshipEntityId], [s].[Id1], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id] +ORDER BY [s].[Id], [s].[BaseInheritanceRelationshipEntityId], [s].[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], [s].[Id], [s].[BaseParentId], [s].[Name], [s].[DerivedProperty], [s].[Discriminator], [s].[Id0], [s].[Name0], [s].[ParentCollectionId], [s].[ParentReferenceId], [s].[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], [s].[Id], [s].[BaseParentId], [s].[Name], [s].[DerivedProperty], [s].[Discriminator], [s].[Id0], [s].[Name0], [s].[ParentCollectionId], [s].[ParentReferenceId], [s].[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 [s] ON [t].[Id] = [s].[BaseParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [s].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [s].[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], [s].[Id], [s].[BaseParentId], [s].[Name], [s].[DerivedProperty], [s].[Discriminator], [s].[Id0], [s].[Name0], [s].[ParentCollectionId], [s].[ParentReferenceId], [s].[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], [s].[Id], [s].[BaseParentId], [s].[Name], [s].[DerivedProperty], [s].[Discriminator], [s].[Id0], [s].[Name0], [s].[ParentCollectionId], [s].[ParentReferenceId], [s].[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 [s] ON [t].[Id] = [s].[BaseParentId] -ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d0].[DerivedInheritanceRelationshipEntityId], [d0].[Id], [s].[Id] +ORDER BY [t].[Id], [o].[BaseInheritanceRelationshipEntityId], [d0].[Id], [o0].[BaseInheritanceRelationshipEntityId], [o0].[Id], [d1].[DerivedInheritanceRelationshipEntityId], [d1].[Id], [s].[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 [s].[Id], [s].[BaseParentId], [s].[Name], [s].[DerivedProperty], [s].[Discriminator], [s].[Id0], [s].[Name0], [s].[ParentCollectionId], [s].[ParentReferenceId], [s].[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 [s] ON [t].[Id] = [s].[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 2f69dc0eb7b..47e42042c0f 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/EntitySplittingQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs index dcc206313e7..4abd2c80239 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/EntitySplittingQuerySqliteTest.cs @@ -370,7 +370,7 @@ public override async Task Tpc_entity_owning_a_split_collection_on_leaf(bool asy AssertSql( """ -SELECT "t"."Id", "t"."BaseValue", "t"."MiddleValue", "t"."SiblingValue", "t"."LeafValue", "t"."Discriminator", "s"."LeafEntityId", "s"."Id", "s"."OwnedIntValue1", "s"."OwnedIntValue2", "s"."OwnedIntValue3", "s"."OwnedIntValue4", "s"."OwnedStringValue1", "s"."OwnedStringValue2", "s"."OwnedStringValue3", "s"."OwnedStringValue4" +SELECT "t"."Id", "t"."BaseValue", "t"."MiddleValue", "t"."SiblingValue", "t"."LeafValue", "t"."Discriminator", "s0"."LeafEntityId", "s0"."Id", "s0"."OwnedIntValue1", "s0"."OwnedIntValue2", "s0"."OwnedIntValue3", "s0"."OwnedIntValue4", "s0"."OwnedStringValue1", "s0"."OwnedStringValue2", "s0"."OwnedStringValue3", "s0"."OwnedStringValue4" FROM ( SELECT "b"."Id", "b"."BaseValue", NULL AS "MiddleValue", NULL AS "SiblingValue", NULL AS "LeafValue", 'BaseEntity' AS "Discriminator" FROM "BaseEntity" AS "b" @@ -378,8 +378,8 @@ UNION ALL SELECT "m"."Id", "m"."BaseValue", "m"."MiddleValue", NULL AS "SiblingValue", NULL AS "LeafValue", 'MiddleEntity' AS "Discriminator" FROM "MiddleEntity" AS "m" UNION ALL - SELECT "s0"."Id", "s0"."BaseValue", NULL AS "MiddleValue", "s0"."SiblingValue", NULL AS "LeafValue", 'SiblingEntity' AS "Discriminator" - FROM "SiblingEntity" AS "s0" + SELECT "s"."Id", "s"."BaseValue", NULL AS "MiddleValue", "s"."SiblingValue", NULL AS "LeafValue", 'SiblingEntity' AS "Discriminator" + FROM "SiblingEntity" AS "s" UNION ALL SELECT "l"."Id", "l"."BaseValue", "l"."MiddleValue", NULL AS "SiblingValue", "l"."LeafValue", 'LeafEntity' AS "Discriminator" FROM "LeafEntity" AS "l" @@ -389,8 +389,8 @@ LEFT JOIN ( FROM "OwnedReferencePart1" AS "o" INNER JOIN "OwnedReferencePart4" AS "o0" ON "o"."LeafEntityId" = "o0"."LeafEntityId" AND "o"."Id" = "o0"."Id" INNER JOIN "OwnedReferencePart3" AS "o1" ON "o"."LeafEntityId" = "o1"."LeafEntityId" AND "o"."Id" = "o1"."Id" -) AS "s" ON "t"."Id" = "s"."LeafEntityId" -ORDER BY "t"."Id", "s"."LeafEntityId" +) AS "s0" ON "t"."Id" = "s0"."LeafEntityId" +ORDER BY "t"."Id", "s0"."LeafEntityId" """); } } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/JsonQuerySqliteTest.cs index b4fc91ab20e..c6c611a7253 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 "o1"."c" FROM ( - SELECT "o0"."OwnedReferenceLeaf" ->> 'SomethingSomething' AS "c", "o0"."key" AS "key0" + SELECT "o0"."OwnedReferenceLeaf" ->> 'SomethingSomething' AS "c", "o0"."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 "o0"."key" LIMIT -1 OFFSET 1 ) AS "o1" - ORDER BY "o1"."key0" + ORDER BY "o1"."key" LIMIT 1 OFFSET 0) = 'e1_r_c2_r' """); }