From 8af9ad12334a6ff44c58798d46ef82e6f4b1677b Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Sat, 11 Feb 2023 13:07:42 +0000 Subject: [PATCH] Don't set table names from DbSet properties when Discriminator property is conflicted with the default but is then configured explicitly (#30234) --- .../TableNameFromDbSetConvention.cs | 19 ++++++++++++++----- .../Query/InheritanceQueryCosmosTest.cs | 8 ++++---- .../Query/InheritanceQueryFixtureBase.cs | 13 ++++++++++++- .../TestModels/InheritanceModel/Drink.cs | 1 + .../TestModels/InheritanceModel/DrinkType.cs | 12 ++++++++++++ .../InheritanceModel/InheritanceContext.cs | 3 +++ .../InheritanceBulkUpdatesSqlServerTest.cs | 4 ++-- ...eteMappingInheritanceQuerySqlServerTest.cs | 8 ++++---- .../Query/InheritanceQuerySqlServerTest.cs | 6 +++--- .../InheritanceBulkUpdatesSqliteTest.cs | 4 ++-- 10 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 test/EFCore.Specification.Tests/TestModels/InheritanceModel/DrinkType.cs diff --git a/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs b/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs index ae6b2e00a8a..51c746dd0ca 100644 --- a/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs @@ -118,12 +118,12 @@ public virtual void ProcessEntityTypeAnnotationChanged( && (entityTypeBuilder.Metadata.GetMappingStrategy() ?? RelationalAnnotationNames.TphMappingStrategy) != RelationalAnnotationNames.TphMappingStrategy) { - foreach (var deriverEntityType in entityTypeBuilder.Metadata.GetDerivedTypesInclusive()) + foreach (var derivedEntityType in entityTypeBuilder.Metadata.GetDerivedTypesInclusive()) { - if (!deriverEntityType.HasSharedClrType - && _sets.TryGetValue(deriverEntityType.ClrType, out var setName)) + if (!derivedEntityType.HasSharedClrType + && _sets.TryGetValue(derivedEntityType.ClrType, out var setName)) { - deriverEntityType.Builder.ToTable(setName); + derivedEntityType.Builder.ToTable(setName); } } } @@ -145,12 +145,21 @@ public virtual void ProcessModelFinalizing( entityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName); } - if (entityType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy + var mappingStrategy = entityType.GetMappingStrategy(); + + if (mappingStrategy == RelationalAnnotationNames.TpcMappingStrategy && entityType.IsAbstract()) { // Undo the convention change if the entity type is mapped using TPC entityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName); } + + if (mappingStrategy == RelationalAnnotationNames.TphMappingStrategy + && entityType.BaseType != null) + { + // Undo the convention change if the hierarchy ultimately ends up TPH + entityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName); + } } } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs index 6a389c4adca..3c3fd5c9640 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/InheritanceQueryCosmosTest.cs @@ -20,21 +20,21 @@ public override async Task Can_query_when_shared_column(bool async) """ SELECT c FROM root c -WHERE (c["Discriminator"] = "Coke") +WHERE (c["Discriminator"] = 1) OFFSET 0 LIMIT 2 """, // """ SELECT c FROM root c -WHERE (c["Discriminator"] = "Lilt") +WHERE (c["Discriminator"] = 2) OFFSET 0 LIMIT 2 """, // """ SELECT c FROM root c -WHERE (c["Discriminator"] = "Tea") +WHERE (c["Discriminator"] = 3) OFFSET 0 LIMIT 2 """); } @@ -47,7 +47,7 @@ public override async Task Can_query_all_types_when_shared_column(bool async) """ SELECT c FROM root c -WHERE c["Discriminator"] IN ("Drink", "Coke", "Lilt", "Tea") +WHERE c["Discriminator"] IN (0, 1, 2, 3) """); } diff --git a/test/EFCore.Specification.Tests/Query/InheritanceQueryFixtureBase.cs b/test/EFCore.Specification.Tests/Query/InheritanceQueryFixtureBase.cs index 39d4021da7d..87591a45c49 100644 --- a/test/EFCore.Specification.Tests/Query/InheritanceQueryFixtureBase.cs +++ b/test/EFCore.Specification.Tests/Query/InheritanceQueryFixtureBase.cs @@ -384,7 +384,18 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con if (HasDiscriminator) { modelBuilder.Entity().HasDiscriminator("Discriminator").IsComplete(IsDiscriminatorMappingComplete); - modelBuilder.Entity().HasDiscriminator().IsComplete(IsDiscriminatorMappingComplete); + + modelBuilder.Entity() + .HasDiscriminator(e => e.Discriminator) + .HasValue(DrinkType.Drink) + .HasValue(DrinkType.Coke) + .HasValue(DrinkType.Lilt) + .HasValue(DrinkType.Tea) + .IsComplete(IsDiscriminatorMappingComplete); + } + else + { + modelBuilder.Entity().Ignore(e => e.Discriminator); } modelBuilder.Entity().HasDiscriminator().IsComplete(IsDiscriminatorMappingComplete); diff --git a/test/EFCore.Specification.Tests/TestModels/InheritanceModel/Drink.cs b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/Drink.cs index e4c5931b43f..7fe069a817b 100644 --- a/test/EFCore.Specification.Tests/TestModels/InheritanceModel/Drink.cs +++ b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/Drink.cs @@ -7,4 +7,5 @@ public class Drink { public int Id { get; set; } public int SortIndex { get; set; } + public DrinkType Discriminator { get; set; } } diff --git a/test/EFCore.Specification.Tests/TestModels/InheritanceModel/DrinkType.cs b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/DrinkType.cs new file mode 100644 index 00000000000..5bdbee4b62b --- /dev/null +++ b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/DrinkType.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.TestModels.InheritanceModel; + +public enum DrinkType +{ + Drink, + Coke, + Lilt, + Tea +} diff --git a/test/EFCore.Specification.Tests/TestModels/InheritanceModel/InheritanceContext.cs b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/InheritanceContext.cs index d99c9f4b31f..dee97caaadf 100644 --- a/test/EFCore.Specification.Tests/TestModels/InheritanceModel/InheritanceContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/InheritanceModel/InheritanceContext.cs @@ -14,6 +14,9 @@ public InheritanceContext(DbContextOptions options) public DbSet AnimalQueries { get; set; } public DbSet Countries { get; set; } public DbSet Drinks { get; set; } + public DbSet Coke { get; set; } + public DbSet Lilt { get; set; } + public DbSet Tea { get; set; } public DbSet Plants { get; set; } public static void Seed(InheritanceContext context, bool useGeneratedKeys) diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqlServerTest.cs index e7dfdc2033d..b6f686916fe 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqlServerTest.cs @@ -218,7 +218,7 @@ public override async Task Update_with_interface_in_property_expression(bool asy UPDATE [d] SET [d].[SugarGrams] = 0 FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Coke' +WHERE [d].[Discriminator] = 1 """); } @@ -231,7 +231,7 @@ public override async Task Update_with_interface_in_EF_Property_in_property_expr UPDATE [d] SET [d].[SugarGrams] = 0 FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Coke' +WHERE [d].[Discriminator] = 1 """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/IncompleteMappingInheritanceQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/IncompleteMappingInheritanceQuerySqlServerTest.cs index 6eb5d677c63..d1114119ee0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/IncompleteMappingInheritanceQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/IncompleteMappingInheritanceQuerySqlServerTest.cs @@ -51,19 +51,19 @@ public override async Task Can_query_when_shared_column(bool async) """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[CaffeineGrams], [d].[CokeCO2], [d].[SugarGrams] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Coke' +WHERE [d].[Discriminator] = 1 """, // """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[LiltCO2], [d].[SugarGrams] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Lilt' +WHERE [d].[Discriminator] = 2 """, // """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[CaffeineGrams], [d].[HasMilk] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Tea' +WHERE [d].[Discriminator] = 3 """); } @@ -103,7 +103,7 @@ public override async Task Can_query_all_types_when_shared_column(bool async) """ SELECT [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[CaffeineGrams], [d].[CokeCO2], [d].[SugarGrams], [d].[LiltCO2], [d].[HasMilk] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] IN (N'Drink', N'Coke', N'Lilt', N'Tea') +WHERE [d].[Discriminator] IN (0, 1, 2, 3) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceQuerySqlServerTest.cs index 9899138e05c..7ef197c91da 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/InheritanceQuerySqlServerTest.cs @@ -48,19 +48,19 @@ public override async Task Can_query_when_shared_column(bool async) """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[CaffeineGrams], [d].[CokeCO2], [d].[SugarGrams] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Coke' +WHERE [d].[Discriminator] = 1 """, // """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[LiltCO2], [d].[SugarGrams] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Lilt' +WHERE [d].[Discriminator] = 2 """, // """ SELECT TOP(2) [d].[Id], [d].[Discriminator], [d].[SortIndex], [d].[CaffeineGrams], [d].[HasMilk] FROM [Drinks] AS [d] -WHERE [d].[Discriminator] = N'Tea' +WHERE [d].[Discriminator] = 3 """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqliteTest.cs index 98b92ec2dd7..849a0f545e1 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/InheritanceBulkUpdatesSqliteTest.cs @@ -207,7 +207,7 @@ public override async Task Update_with_interface_in_property_expression(bool asy """ UPDATE "Drinks" AS "d" SET "SugarGrams" = 0 -WHERE "d"."Discriminator" = 'Coke' +WHERE "d"."Discriminator" = 1 """); } @@ -219,7 +219,7 @@ public override async Task Update_with_interface_in_EF_Property_in_property_expr """ UPDATE "Drinks" AS "d" SET "SugarGrams" = 0 -WHERE "d"."Discriminator" = 'Coke' +WHERE "d"."Discriminator" = 1 """); }