diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index d8638a86264..4988086a1e2 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -906,65 +906,68 @@ protected virtual void GenerateKeyAnnotations(string keyBuilderName, IKey key, I ?? discriminatorValueAnnotation?.Value) != null) { - stringBuilder - .AppendLine() - .Append(entityTypeBuilderName) - .Append('.') - .Append("HasDiscriminator"); - var discriminatorProperty = entityType.FindDiscriminatorProperty(); - if (discriminatorPropertyAnnotation?.Value != null - && discriminatorProperty != null) - { - var propertyClrType = FindValueConverter(discriminatorProperty)?.ProviderClrType - .MakeNullable(discriminatorProperty.IsNullable) - ?? discriminatorProperty.ClrType; - stringBuilder - .Append('<') - .Append(Code.Reference(propertyClrType)) - .Append(">(") - .Append(Code.Literal(discriminatorProperty.Name)) - .Append(')'); - } - else + if (discriminatorProperty != null) { stringBuilder - .Append("()"); - } + .AppendLine() + .Append(entityTypeBuilderName) + .Append('.') + .Append("HasDiscriminator"); - if (discriminatorMappingCompleteAnnotation?.Value != null) - { - var value = (bool)discriminatorMappingCompleteAnnotation.Value; + if (discriminatorProperty.DeclaringType == entityType + && discriminatorProperty.Name != "Discriminator") + { + var propertyClrType = FindValueConverter(discriminatorProperty)?.ProviderClrType + .MakeNullable(discriminatorProperty.IsNullable) + ?? discriminatorProperty.ClrType; + stringBuilder + .Append('<') + .Append(Code.Reference(propertyClrType)) + .Append(">(") + .Append(Code.Literal(discriminatorProperty.Name)) + .Append(')'); + } + else + { + stringBuilder + .Append("()"); + } - stringBuilder - .Append('.') - .Append("IsComplete") - .Append('(') - .Append(Code.Literal(value)) - .Append(')'); - } + if (discriminatorMappingCompleteAnnotation?.Value != null) + { + var value = (bool)discriminatorMappingCompleteAnnotation.Value; - if (discriminatorValueAnnotation?.Value != null) - { - var value = discriminatorValueAnnotation.Value; - if (discriminatorProperty != null) + stringBuilder + .Append('.') + .Append("IsComplete") + .Append('(') + .Append(Code.Literal(value)) + .Append(')'); + } + + if (discriminatorValueAnnotation?.Value != null) { - var valueConverter = FindValueConverter(discriminatorProperty); - if (valueConverter != null) + var value = discriminatorValueAnnotation.Value; + if (discriminatorProperty != null) { - value = valueConverter.ConvertToProvider(value); + var valueConverter = FindValueConverter(discriminatorProperty); + if (valueConverter != null) + { + value = valueConverter.ConvertToProvider(value); + } } + + stringBuilder + .Append('.') + .Append("HasValue") + .Append('(') + .Append(Code.UnknownLiteral(value)) + .Append(')'); } - stringBuilder - .Append('.') - .Append("HasValue") - .Append('(') - .Append(Code.UnknownLiteral(value)) - .Append(')'); + stringBuilder.AppendLine(";"); } - - stringBuilder.AppendLine(";"); } GenerateAnnotations(entityTypeBuilderName, entityType, stringBuilder, annotations, inChainedCall: false); diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs index a7d5694c673..d54a2f1ade0 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs @@ -1236,6 +1236,105 @@ protected override void BuildModel(ModelBuilder modelBuilder) Assert.Null(humanPetType.GetViewName()); }); + [ConditionalFact] // Issue #33605 + public virtual void Abstract_base_class_with_TPT() + => Test( + builder => + { + builder.Entity().ToTable("Cats"); + builder.Entity().ToTable("Dogs"); + builder.Entity(); + builder.Ignore(); + builder.Ignore(); + builder.Ignore(); + }, + """ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace RootNamespace +{ + [DbContext(typeof(DbContext))] + partial class Snapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("DefaultSchema") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Cat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("EducationLevel") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Vet") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Cats", "DefaultSchema"); + }); + + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Dog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FavoriteToy") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Vet") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Dogs", "DefaultSchema"); + }); +#pragma warning restore 612, 618 + } + } +} + +""", + model => + { + Assert.Equal(5, model.GetAnnotations().Count()); + Assert.Equal(2, model.GetEntityTypes().Count()); + + var catType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Cat"); + Assert.Equal("Cats", catType.GetTableName()); + Assert.Null(catType.GetViewName()); + Assert.Null(catType.FindProperty("Discriminator")); + + var dogType = model.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTest+Dog"); + Assert.Equal("Dogs", dogType.GetTableName()); + Assert.Null(dogType.GetViewName()); + }); + [ConditionalFact] public virtual void Entity_splitting_is_stored_in_snapshot_with_tables() => Test( @@ -1919,7 +2018,7 @@ public virtual void CheckConstraint_is_only_stored_in_snapshot_once_for_TPH() b.ToTable("BaseEntity", "DefaultSchema"); - b.HasDiscriminator("Discriminator").HasValue("BaseEntity"); + b.HasDiscriminator().HasValue("BaseEntity"); b.UseTphMappingStrategy(); }); @@ -2252,7 +2351,7 @@ public virtual void BaseType_is_stored_in_snapshot() b.ToTable("BaseEntity", "DefaultSchema"); - b.HasDiscriminator("Discriminator").HasValue("BaseEntity"); + b.HasDiscriminator().HasValue("BaseEntity"); b.UseTphMappingStrategy(); }); @@ -2323,7 +2422,7 @@ public virtual void Discriminator_annotations_are_stored_in_snapshot() b.ToTable("BaseEntity", "DefaultSchema"); - b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("BaseEntity"); + b.HasDiscriminator().IsComplete(true).HasValue("BaseEntity"); b.UseTphMappingStrategy(); }); @@ -2399,7 +2498,7 @@ public virtual void Converted_discriminator_annotations_are_stored_in_snapshot() b.ToTable("BaseEntityWithStructDiscriminator", "DefaultSchema"); - b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("Base"); + b.HasDiscriminator().IsComplete(true).HasValue("Base"); b.UseTphMappingStrategy(); }); @@ -4855,7 +4954,7 @@ public virtual void Property_column_name_is_stored_in_snapshot_when_DefaultColum b.ToTable("BarBase", "DefaultSchema"); - b.HasDiscriminator("Discriminator").HasValue("BarBase"); + b.HasDiscriminator().HasValue("BarBase"); b.UseTphMappingStrategy(); }); @@ -5071,7 +5170,7 @@ public virtual void Property_column_name_on_specific_table_is_stored_in_snapshot b.ToTable("BaseEntity", "DefaultSchema"); - b.HasDiscriminator("Discriminator").HasValue("BaseEntity"); + b.HasDiscriminator().HasValue("BaseEntity"); b.UseTphMappingStrategy(); }); @@ -7398,7 +7497,7 @@ public virtual void Do_not_generate_entity_type_builder_again_if_no_foreign_key_ b.ToTable("BaseType", "DefaultSchema"); - b.HasDiscriminator("Discriminator").HasValue("BaseType"); + b.HasDiscriminator().HasValue("BaseType"); b.UseTphMappingStrategy(); }); diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 411a97bee83..70997837f36 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -135,14 +135,7 @@ public void Test_new_annotations_handled_for_entity_types() }, { CoreAnnotationNames.DiscriminatorValue, ("MyDiscriminatorValue", - _toTable - + ";" - + _nl - + _nl - + "entityTypeBuilder.HasDiscriminator" - + "()." - + nameof(DiscriminatorBuilder.HasValue) - + @"(""MyDiscriminatorValue"")") + _toTable) }, { RelationalAnnotationNames.Comment, ("My Comment",