From bb003c835796bef42975e7bfd88dbf6624ebe7e7 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Fri, 4 Sep 2020 17:52:13 -0700 Subject: [PATCH] Make sure non-shared-type entity types aren't discovered while a shared-type entity type is being added Fixes #22406 --- .../Metadata/Internal/InternalModelBuilder.cs | 1 + .../ManyToManyTrackingTestBase.cs | 10 +- .../Query/ManyToManyQueryFixtureBase.cs | 5 +- .../ManyToManyLoadSqlServerTest.cs | 9 +- .../ManyToManyTrackingProxySqlServerTest.cs | 25 +++ .../ManyToManyTrackingSqlServerTestBase.cs | 9 +- .../Query/ManyToManyQuerySqlServerTest.cs | 138 ++++++++------- .../Query/TPTManyToManyQuerySqlServerTest.cs | 158 +++++++++--------- .../ManyToManyLoadSqliteTestBase.cs | 9 +- .../ManyToManyTrackingSqliteTest.cs | 9 +- .../Conventions/ConventionDispatcherTest.cs | 2 +- .../ModelBuilding/ManyToManyTestBase.cs | 4 +- 12 files changed, 197 insertions(+), 182 deletions(-) diff --git a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs index 7770b62512b..f58e466ac19 100644 --- a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs @@ -88,6 +88,7 @@ private InternalEntityTypeBuilder Entity( return null; } + using var batch = Metadata.ConventionDispatcher.DelayConventions(); var clrType = type.Type; EntityType entityType; if (type.IsNamed) diff --git a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs index 592cf0ffd63..7bbc9c7d200 100644 --- a/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs +++ b/test/EFCore.Specification.Tests/ManyToManyTrackingTestBase.cs @@ -1846,7 +1846,7 @@ static void ValidateFixup( } } - [ConditionalFact(Skip = "Issue #22406")] + [ConditionalFact] public virtual void Can_insert_many_to_many_shared_with_payload() { ExecuteWithStrategyInTransaction( @@ -1920,7 +1920,7 @@ void ValidateFixup(DbContext context, IList leftEntities, IList @@ -3038,7 +3038,7 @@ public void Can_insert_update_delete_shared_type_entity_type() } [ConditionalFact] - public void Can_insert_update_delete_proxyable_shared_type_entity_type() + public virtual void Can_insert_update_delete_proxyable_shared_type_entity_type() { ExecuteWithStrategyInTransaction( context => diff --git a/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs index 89c5898cf74..aac3a89a346 100644 --- a/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/ManyToManyQueryFixtureBase.cs @@ -208,9 +208,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .UsingEntity>( "JoinOneToThreePayloadFullShared", r => r.HasOne().WithMany(e => e.JoinOnePayloadFullShared).HasForeignKey("ThreeId"), - l => l.HasOne().WithMany(e => e.JoinThreePayloadFullShared).HasForeignKey("OneId")); - // Disabled - see #22406 - //.IndexerProperty("Payload"); + l => l.HasOne().WithMany(e => e.JoinThreePayloadFullShared).HasForeignKey("OneId")) + .IndexerProperty("Payload"); // Nav:6 Payload:Yes Join:Concrete Extra:Self-Ref modelBuilder.Entity() diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs index f916b0c930a..68a402bfc7e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyLoadSqlServerTest.cs @@ -110,11 +110,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .Property(e => e.Payload) .HasDefaultValueSql("GETUTCDATE()"); - // Disabled - see #22406 - // modelBuilder - // .SharedTypeEntity>("JoinOneToThreePayloadFullShared") - // .IndexerProperty("Payload") - // .HasDefaultValue("Generated"); + modelBuilder + .SharedTypeEntity>("JoinOneToThreePayloadFullShared") + .IndexerProperty("Payload") + .HasDefaultValue("Generated"); modelBuilder .Entity() diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingProxySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingProxySqlServerTest.cs index de062222dfe..6681610c76e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingProxySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingProxySqlServerTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore @@ -13,6 +14,21 @@ public ManyToManyTrackingProxySqlServerTest(ManyToManyTrackingProxySqlServerFixt { } + public override void Can_insert_many_to_many_shared_with_payload() + { + // Mutable properties aren't proxyable on Dictionary + } + + public override void Can_update_many_to_many_shared_with_payload() + { + // Mutable properties aren't proxyable on Dictionary + } + + public override void Can_insert_update_delete_shared_type_entity_type() + { + // Mutable properties aren't proxyable on Dictionary + } + protected override bool RequiresDetectChanges => false; @@ -25,6 +41,15 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build protected override IServiceCollection AddServices(IServiceCollection serviceCollection) => base.AddServices(serviceCollection.AddEntityFrameworkProxies()); + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder + .SharedTypeEntity>("JoinOneToThreePayloadFullShared") + .Ignore("Payload"); // Mutable properties aren't proxyable on Dictionary + } } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingSqlServerTestBase.cs b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingSqlServerTestBase.cs index 335e0a19444..a88472ec150 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingSqlServerTestBase.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ManyToManyTrackingSqlServerTestBase.cs @@ -34,11 +34,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .Property(e => e.Payload) .HasDefaultValueSql("GETUTCDATE()"); - // Disabled - see #22406 - // modelBuilder - // .SharedTypeEntity>("JoinOneToThreePayloadFullShared") - // .IndexerProperty("Payload") - // .HasDefaultValue("Generated"); + modelBuilder + .SharedTypeEntity>("JoinOneToThreePayloadFullShared") + .IndexerProperty("Payload") + .HasDefaultValue("Generated"); modelBuilder .Entity() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs index eb147b4762f..6766a6cb4d2 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs @@ -659,17 +659,16 @@ public override async Task Filtered_include_skip_navigation_where(bool async) { await base.Filtered_include_skip_navigation_where(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name] -// FROM [EntityThrees] AS [e] -// LEFT JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] -// WHERE [e0].[Id] < 10 -// ) AS [t] ON [e].[Id] = [t].[ThreeId] -// ORDER BY [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id]"); + AssertSql( + @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name] +FROM [EntityThrees] AS [e] +LEFT JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] + WHERE [e0].[Id] < 10 +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by(bool async) @@ -748,22 +747,21 @@ public override async Task Filtered_then_include_skip_navigation_where(bool asyn { await base.Filtered_then_include_skip_navigation_where(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[Discriminator], [e].[Name], [e].[Number], [e].[IsGreen], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id0], [t0].[Name0] -// FROM [EntityRoots] AS [e] -// LEFT JOIN ( -// SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id] AS [Id0], [t].[Name] AS [Name0] -// FROM [EntityRootEntityThree] AS [e0] -// INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] -// LEFT JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e2].[Id], [e2].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e2] ON [j].[OneId] = [e2].[Id] -// WHERE [e2].[Id] < 10 -// ) AS [t] ON [e1].[Id] = [t].[ThreeId] -// ) AS [t0] ON [e].[Id] = [t0].[EntityRootId] -// ORDER BY [e].[Id], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[OneId], [t0].[ThreeId], [t0].[Id0]"); + AssertSql( + @"SELECT [e].[Id], [e].[Discriminator], [e].[Name], [e].[Number], [e].[IsGreen], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id0], [t0].[Name0] +FROM [EntityRoots] AS [e] +LEFT JOIN ( + SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id] AS [Id0], [t].[Name] AS [Name0] + FROM [EntityRootEntityThree] AS [e0] + INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] + LEFT JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e2].[Id], [e2].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e2] ON [j].[OneId] = [e2].[Id] + WHERE [e2].[Id] < 10 + ) AS [t] ON [e1].[Id] = [t].[ThreeId] +) AS [t0] ON [e].[Id] = [t0].[EntityRootId] +ORDER BY [e].[Id], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[OneId], [t0].[ThreeId], [t0].[Id0]"); } public override async Task Filtered_then_include_skip_navigation_order_by_skip_take(bool async) @@ -1113,21 +1111,20 @@ public override async Task Filtered_include_skip_navigation_where_split(bool asy { await base.Filtered_include_skip_navigation_where_split(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId] -// FROM [EntityThrees] AS [e] -// ORDER BY [e].[Id]", -// // -// @"SELECT [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name], [e].[Id] -// FROM [EntityThrees] AS [e] -// INNER JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] -// WHERE [e0].[Id] < 10 -// ) AS [t] ON [e].[Id] = [t].[ThreeId] -// ORDER BY [e].[Id]"); + AssertSql( + @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId] +FROM [EntityThrees] AS [e] +ORDER BY [e].[Id]", + // + @"SELECT [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name], [e].[Id] +FROM [EntityThrees] AS [e] +INNER JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] + WHERE [e0].[Id] < 10 +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_split(bool async) @@ -1226,35 +1223,34 @@ public override async Task Filtered_then_include_skip_navigation_where_split(boo { await base.Filtered_then_include_skip_navigation_where_split(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[Discriminator], [e].[Name], [e].[Number], [e].[IsGreen] -// FROM [EntityRoots] AS [e] -// ORDER BY [e].[Id]", -// // -// @"SELECT [t].[EntityRootId], [t].[EntityThreeId], [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] -// FROM [EntityRoots] AS [e] -// INNER JOIN ( -// SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] -// FROM [EntityRootEntityThree] AS [e0] -// INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] -// ) AS [t] ON [e].[Id] = [t].[EntityRootId] -// ORDER BY [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]", -// // -// @"SELECT [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id], [t0].[Name], [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] -// FROM [EntityRoots] AS [e] -// INNER JOIN ( -// SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id] -// FROM [EntityRootEntityThree] AS [e0] -// INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] -// ) AS [t] ON [e].[Id] = [t].[EntityRootId] -// INNER JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e2].[Id], [e2].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e2] ON [j].[OneId] = [e2].[Id] -// WHERE [e2].[Id] < 10 -// ) AS [t0] ON [t].[Id] = [t0].[ThreeId] -// ORDER BY [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]"); + AssertSql( + @"SELECT [e].[Id], [e].[Discriminator], [e].[Name], [e].[Number], [e].[IsGreen] +FROM [EntityRoots] AS [e] +ORDER BY [e].[Id]", + // + @"SELECT [t].[EntityRootId], [t].[EntityThreeId], [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [e].[Id] +FROM [EntityRoots] AS [e] +INNER JOIN ( + SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id], [e1].[CollectionInverseId], [e1].[Name], [e1].[ReferenceInverseId] + FROM [EntityRootEntityThree] AS [e0] + INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] +) AS [t] ON [e].[Id] = [t].[EntityRootId] +ORDER BY [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]", + // + @"SELECT [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id], [t0].[Name], [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] +FROM [EntityRoots] AS [e] +INNER JOIN ( + SELECT [e0].[EntityRootId], [e0].[EntityThreeId], [e1].[Id] + FROM [EntityRootEntityThree] AS [e0] + INNER JOIN [EntityThrees] AS [e1] ON [e0].[EntityThreeId] = [e1].[Id] +) AS [t] ON [e].[Id] = [t].[EntityRootId] +INNER JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e2].[Id], [e2].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e2] ON [j].[OneId] = [e2].[Id] + WHERE [e2].[Id] < 10 +) AS [t0] ON [t].[Id] = [t0].[ThreeId] +ORDER BY [e].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]"); } public override async Task Filtered_then_include_skip_navigation_order_by_skip_take_split(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs index e78818c257f..5f4b1e27d74 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs @@ -695,17 +695,16 @@ public override async Task Filtered_include_skip_navigation_where(bool async) { await base.Filtered_include_skip_navigation_where(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name] -// FROM [EntityThrees] AS [e] -// LEFT JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] -// WHERE [e0].[Id] < 10 -// ) AS [t] ON [e].[Id] = [t].[ThreeId] -// ORDER BY [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id]"); + AssertSql( + @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name] +FROM [EntityThrees] AS [e] +LEFT JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] + WHERE [e0].[Id] < 10 +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id], [t].[OneId], [t].[ThreeId], [t].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by(bool async) @@ -784,27 +783,26 @@ public override async Task Filtered_then_include_skip_navigation_where(bool asyn { await base.Filtered_then_include_skip_navigation_where(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE -// WHEN [l].[Id] IS NOT NULL THEN N'EntityLeaf' -// WHEN [b].[Id] IS NOT NULL THEN N'EntityBranch' -// END AS [Discriminator], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id0], [t0].[Name0] -// FROM [Roots] AS [r] -// LEFT JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] -// LEFT JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] -// LEFT JOIN ( -// SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id] AS [Id0], [t].[Name] AS [Name0] -// FROM [EntityRootEntityThree] AS [e] -// INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] -// LEFT JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e1].[Id], [e1].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e1] ON [j].[OneId] = [e1].[Id] -// WHERE [e1].[Id] < 10 -// ) AS [t] ON [e0].[Id] = [t].[ThreeId] -// ) AS [t0] ON [r].[Id] = [t0].[EntityRootId] -// ORDER BY [r].[Id], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[OneId], [t0].[ThreeId], [t0].[Id0]"); + AssertSql( + @"SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE + WHEN [l].[Id] IS NOT NULL THEN N'EntityLeaf' + WHEN [b].[Id] IS NOT NULL THEN N'EntityBranch' +END AS [Discriminator], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[CollectionInverseId], [t0].[Name], [t0].[ReferenceInverseId], [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id0], [t0].[Name0] +FROM [Roots] AS [r] +LEFT JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] +LEFT JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] +LEFT JOIN ( + SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId], [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id] AS [Id0], [t].[Name] AS [Name0] + FROM [EntityRootEntityThree] AS [e] + INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] + LEFT JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e1].[Id], [e1].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e1] ON [j].[OneId] = [e1].[Id] + WHERE [e1].[Id] < 10 + ) AS [t] ON [e0].[Id] = [t].[ThreeId] +) AS [t0] ON [r].[Id] = [t0].[EntityRootId] +ORDER BY [r].[Id], [t0].[EntityRootId], [t0].[EntityThreeId], [t0].[Id], [t0].[OneId], [t0].[ThreeId], [t0].[Id0]"); } public override async Task Filtered_then_include_skip_navigation_order_by_skip_take(bool async) @@ -1173,21 +1171,20 @@ public override async Task Filtered_include_skip_navigation_where_split(bool asy { await base.Filtered_include_skip_navigation_where_split(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId] -// FROM [EntityThrees] AS [e] -// ORDER BY [e].[Id]", -// // -// @"SELECT [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name], [e].[Id] -// FROM [EntityThrees] AS [e] -// INNER JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] -// WHERE [e0].[Id] < 10 -// ) AS [t] ON [e].[Id] = [t].[ThreeId] -// ORDER BY [e].[Id]"); + AssertSql( + @"SELECT [e].[Id], [e].[CollectionInverseId], [e].[Name], [e].[ReferenceInverseId] +FROM [EntityThrees] AS [e] +ORDER BY [e].[Id]", + // + @"SELECT [t].[OneId], [t].[ThreeId], [t].[Payload], [t].[Id], [t].[Name], [e].[Id] +FROM [EntityThrees] AS [e] +INNER JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e0].[Id], [e0].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e0] ON [j].[OneId] = [e0].[Id] + WHERE [e0].[Id] < 10 +) AS [t] ON [e].[Id] = [t].[ThreeId] +ORDER BY [e].[Id]"); } public override async Task Filtered_include_skip_navigation_order_by_split(bool async) @@ -1286,40 +1283,39 @@ public override async Task Filtered_then_include_skip_navigation_where_split(boo { await base.Filtered_then_include_skip_navigation_where_split(async); - // Payload has been removed -- see #22406 -// AssertSql( -// @"SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE -// WHEN [l].[Id] IS NOT NULL THEN N'EntityLeaf' -// WHEN [b].[Id] IS NOT NULL THEN N'EntityBranch' -// END AS [Discriminator] -// FROM [Roots] AS [r] -// LEFT JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] -// LEFT JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] -// ORDER BY [r].[Id]", -// // -// @"SELECT [t].[EntityRootId], [t].[EntityThreeId], [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [r].[Id] -// FROM [Roots] AS [r] -// INNER JOIN ( -// SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId] -// FROM [EntityRootEntityThree] AS [e] -// INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] -// ) AS [t] ON [r].[Id] = [t].[EntityRootId] -// ORDER BY [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]", -// // -// @"SELECT [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id], [t0].[Name], [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] -// FROM [Roots] AS [r] -// INNER JOIN ( -// SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id] -// FROM [EntityRootEntityThree] AS [e] -// INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] -// ) AS [t] ON [r].[Id] = [t].[EntityRootId] -// INNER JOIN ( -// SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e1].[Id], [e1].[Name] -// FROM [JoinOneToThreePayloadFullShared] AS [j] -// INNER JOIN [EntityOnes] AS [e1] ON [j].[OneId] = [e1].[Id] -// WHERE [e1].[Id] < 10 -// ) AS [t0] ON [t].[Id] = [t0].[ThreeId] -// ORDER BY [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]"); + AssertSql( + @"SELECT [r].[Id], [r].[Name], [b].[Number], [l].[IsGreen], CASE + WHEN [l].[Id] IS NOT NULL THEN N'EntityLeaf' + WHEN [b].[Id] IS NOT NULL THEN N'EntityBranch' +END AS [Discriminator] +FROM [Roots] AS [r] +LEFT JOIN [Branches] AS [b] ON [r].[Id] = [b].[Id] +LEFT JOIN [Leaves] AS [l] ON [r].[Id] = [l].[Id] +ORDER BY [r].[Id]", + // + @"SELECT [t].[EntityRootId], [t].[EntityThreeId], [t].[Id], [t].[CollectionInverseId], [t].[Name], [t].[ReferenceInverseId], [r].[Id] +FROM [Roots] AS [r] +INNER JOIN ( + SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id], [e0].[CollectionInverseId], [e0].[Name], [e0].[ReferenceInverseId] + FROM [EntityRootEntityThree] AS [e] + INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] +) AS [t] ON [r].[Id] = [t].[EntityRootId] +ORDER BY [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]", + // + @"SELECT [t0].[OneId], [t0].[ThreeId], [t0].[Payload], [t0].[Id], [t0].[Name], [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id] +FROM [Roots] AS [r] +INNER JOIN ( + SELECT [e].[EntityRootId], [e].[EntityThreeId], [e0].[Id] + FROM [EntityRootEntityThree] AS [e] + INNER JOIN [EntityThrees] AS [e0] ON [e].[EntityThreeId] = [e0].[Id] +) AS [t] ON [r].[Id] = [t].[EntityRootId] +INNER JOIN ( + SELECT [j].[OneId], [j].[ThreeId], [j].[Payload], [e1].[Id], [e1].[Name] + FROM [JoinOneToThreePayloadFullShared] AS [j] + INNER JOIN [EntityOnes] AS [e1] ON [j].[OneId] = [e1].[Id] + WHERE [e1].[Id] < 10 +) AS [t0] ON [t].[Id] = [t0].[ThreeId] +ORDER BY [r].[Id], [t].[EntityRootId], [t].[EntityThreeId], [t].[Id]"); } public override async Task Filtered_then_include_skip_navigation_order_by_skip_take_split(bool async) diff --git a/test/EFCore.Sqlite.FunctionalTests/ManyToManyLoadSqliteTestBase.cs b/test/EFCore.Sqlite.FunctionalTests/ManyToManyLoadSqliteTestBase.cs index 877b9728035..30991d1480e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ManyToManyLoadSqliteTestBase.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ManyToManyLoadSqliteTestBase.cs @@ -29,11 +29,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .Property(e => e.Payload) .HasDefaultValueSql("CURRENT_TIMESTAMP"); - // Disabled - see #22406 - // modelBuilder - // .SharedTypeEntity>("JoinOneToThreePayloadFullShared") - // .IndexerProperty("Payload") - // .HasDefaultValue("Generated"); + modelBuilder + .SharedTypeEntity>("JoinOneToThreePayloadFullShared") + .IndexerProperty("Payload") + .HasDefaultValue("Generated"); modelBuilder .Entity() diff --git a/test/EFCore.Sqlite.FunctionalTests/ManyToManyTrackingSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ManyToManyTrackingSqliteTest.cs index 6cba695d702..eeb8169832d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ManyToManyTrackingSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ManyToManyTrackingSqliteTest.cs @@ -33,11 +33,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con .Property(e => e.Payload) .HasDefaultValueSql("CURRENT_TIMESTAMP"); - // Disabled - see #22406 - // modelBuilder - // .SharedTypeEntity>("JoinOneToThreePayloadFullShared") - // .IndexerProperty("Payload") - // .HasDefaultValue("Generated"); + modelBuilder + .SharedTypeEntity>("JoinOneToThreePayloadFullShared") + .IndexerProperty("Payload") + .HasDefaultValue("Generated"); modelBuilder .Entity() diff --git a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs index 17e8f8d7cef..a0494651bb8 100644 --- a/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/ConventionDispatcherTest.cs @@ -242,7 +242,7 @@ public void OnEntityTypeAdded_calls_conventions_in_order(bool useBuilder, bool u { var result = builder.Entity(typeof(Order), ConfigurationSource.Convention); - Assert.Equal(!useScope, result == null); + Assert.NotNull(result); } else { diff --git a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs index e314460307c..44f190a31a2 100644 --- a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs @@ -403,7 +403,7 @@ public virtual void Can_use_shared_Type_as_join_entity() modelBuilder.Entity().HasKey(d => d.Id); modelBuilder.Entity().HasKey(d => d.DependentWithFieldId); - var model = modelBuilder.FinalizeModel(); + var model = modelBuilder.Model; var shared1 = model.FindEntityType("Shared1"); Assert.NotNull(shared1); @@ -433,6 +433,8 @@ public virtual void Can_use_shared_Type_as_join_entity() Assert.Equal( CoreStrings.ClashingSharedType(typeof(Dictionary).DisplayName()), Assert.Throws(() => modelBuilder.Entity>()).Message); + + modelBuilder.FinalizeModel(); } [ConditionalFact]