From c022c8b022a527e5f83e63ae519fe214122fde16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 03:07:08 +0000 Subject: [PATCH 1/5] Initial plan From f3c4724a4096712706f34e61cfaccf15001befa9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 03:15:59 +0000 Subject: [PATCH 2/5] Append timestamp to scaffolded migration type names When scaffolding a new migration, the type name now includes the timestamp from the migration ID. For example, a migration named "DateTime" will generate a type named "DateTime_20250512080000" instead of just "DateTime", avoiding conflicts with .NET types and potential C# keyword warnings. Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../Migrations/Design/MigrationsScaffolder.cs | 5 +++-- .../Migrations/Design/MigrationScaffolderTest.cs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs index 7698372b3a1..66c12899c05 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs @@ -172,15 +172,16 @@ public virtual ScaffoldedMigration ScaffoldMigration( } var codeGenerator = Dependencies.MigrationsCodeGeneratorSelector.Select(language); + var migrationTypeName = migrationName + "_" + migrationId[..migrationId.IndexOf('_')]; var migrationCode = codeGenerator.GenerateMigration( migrationNamespace, - migrationName, + migrationTypeName, upOperations, downOperations); var migrationMetadataCode = codeGenerator.GenerateMetadata( migrationNamespace, _contextType, - migrationName, + migrationTypeName, migrationId, Dependencies.Model); var modelSnapshotCode = codeGenerator.GenerateSnapshot( diff --git a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs index 016c5f00b0f..fbb9ab509e5 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -51,6 +51,19 @@ public void ScaffoldMigration_can_override_namespace() Assert.Equal("OverrideNamespace.OverrideSubNamespace", migration.SnapshotSubnamespace); } + [ConditionalFact] + public void ScaffoldMigration_appends_timestamp_to_type_name() + { + var scaffolder = CreateMigrationScaffolder(); + + var migration = scaffolder.ScaffoldMigration("DateTime", "WebApplication1"); + + var timestamp = migration.MigrationId[..migration.MigrationId.IndexOf('_')]; + Assert.Contains($"public partial class DateTime_{timestamp} : Migration", migration.MigrationCode); + Assert.Contains($"partial class DateTime_{timestamp}", migration.MetadataCode); + Assert.Contains($"[Migration(\"{migration.MigrationId}\")]", migration.MetadataCode); + } + private IMigrationsScaffolder CreateMigrationScaffolder() where TContext : DbContext, new() { From 7317eff7e42430adbaf819ec1e1e2bbd421bc5ef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 08:40:11 +0000 Subject: [PATCH 3/5] Use migration ID directly as the type name Simplify by passing the migration ID directly as the type name instead of constructing Name_Timestamp. The Code.Identifier() call in the code generator handles making it a valid C# identifier. Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs | 5 ++--- .../Migrations/Design/MigrationScaffolderTest.cs | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs index 66c12899c05..c2ca85b3b0f 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs @@ -172,16 +172,15 @@ public virtual ScaffoldedMigration ScaffoldMigration( } var codeGenerator = Dependencies.MigrationsCodeGeneratorSelector.Select(language); - var migrationTypeName = migrationName + "_" + migrationId[..migrationId.IndexOf('_')]; var migrationCode = codeGenerator.GenerateMigration( migrationNamespace, - migrationTypeName, + migrationId, upOperations, downOperations); var migrationMetadataCode = codeGenerator.GenerateMetadata( migrationNamespace, _contextType, - migrationTypeName, + migrationId, migrationId, Dependencies.Model); var modelSnapshotCode = codeGenerator.GenerateSnapshot( diff --git a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs index fbb9ab509e5..36bdd0f248f 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -58,9 +58,8 @@ public void ScaffoldMigration_appends_timestamp_to_type_name() var migration = scaffolder.ScaffoldMigration("DateTime", "WebApplication1"); - var timestamp = migration.MigrationId[..migration.MigrationId.IndexOf('_')]; - Assert.Contains($"public partial class DateTime_{timestamp} : Migration", migration.MigrationCode); - Assert.Contains($"partial class DateTime_{timestamp}", migration.MetadataCode); + Assert.Contains($"public partial class _{migration.MigrationId} : Migration", migration.MigrationCode); + Assert.Contains($"partial class _{migration.MigrationId}", migration.MetadataCode); Assert.Contains($"[Migration(\"{migration.MigrationId}\")]", migration.MetadataCode); } From 035f6359f1d695fd97577c83f26a2e08baf8e972 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 08:54:37 +0000 Subject: [PATCH 4/5] Fix test baselines for migration ID-based type names Update expected type names in OperationExecutorTest and HierarchyId MigrationTests to reflect migration ID being used as the type name (prefixed with _ since IDs start with a digit). Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- test/EFCore.Design.Tests/Design/OperationExecutorTest.cs | 5 +++-- test/EFCore.SqlServer.HierarchyId.Tests/MigrationTests.cs | 4 ++-- .../TestModels/Migrations/AnonymousArraySeedContext.cs | 4 ++-- .../TestModels/Migrations/MigrationContext.cs | 2 +- .../TestModels/Migrations/TypedArraySeedContext.cs | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs b/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs index 7e185a7610b..6b0257e285d 100644 --- a/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs +++ b/test/EFCore.Design.Tests/Design/OperationExecutorTest.cs @@ -76,6 +76,7 @@ private void TestAddMigrationPositive( string processedOutputDir, string productVersion) { + var migrationTypeName = $"_11112233445566_{processedMigrationName}"; using var tempPath = new TempDirectory(); var resultHandler = ExecuteAddMigration(tempPath, migrationName, Path.Combine(tempPath, outputDir), productVersion); @@ -124,7 +125,7 @@ namespace My.Gnomespace.Data { [DbContext(typeof(OperationExecutorTest.GnomeContext))] [Migration("11112233445566_{{migrationName}}")] - partial class {{processedMigrationName}} + partial class {{migrationTypeName}} { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -147,7 +148,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) namespace My.Gnomespace.Data { /// - public partial class {{processedMigrationName}} : Migration + public partial class {{migrationTypeName}} : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/MigrationTests.cs b/test/EFCore.SqlServer.HierarchyId.Tests/MigrationTests.cs index 8513756aa09..cfe9ec410e1 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/MigrationTests.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/MigrationTests.cs @@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer; public class MigrationTests { - private delegate string MigrationCodeGetter(string migrationName, string rootNamespace); + private delegate string MigrationCodeGetter(string migrationId, string rootNamespace); private delegate string SnapshotCodeGetter(string rootNamespace, string migrationId); @@ -56,7 +56,7 @@ private static void ValidateMigrationAndSnapshotCode( .GetRequiredService() .ScaffoldMigration(migrationName, rootNamespace); - var expectedMigration = migrationCodeGetter(migrationName, rootNamespace); + var expectedMigration = migrationCodeGetter(migration.MigrationId, rootNamespace); var expectedSnapshot = snapshotCodeGetter(rootNamespace, migration.MigrationId); Assert.Equal(expectedMigration, migration.MigrationCode, ignoreLineEndingDifferences: true); diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/AnonymousArraySeedContext.cs b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/AnonymousArraySeedContext.cs index 174170aa2bb..856e1e42d1e 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/AnonymousArraySeedContext.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/AnonymousArraySeedContext.cs @@ -41,7 +41,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); } - public override string GetExpectedMigrationCode(string migrationName, string rootNamespace) + public override string GetExpectedMigrationCode(string migrationId, string rootNamespace) => $@"using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.SqlServer.Types; @@ -52,7 +52,7 @@ public override string GetExpectedMigrationCode(string migrationName, string roo namespace {rootNamespace}.Migrations {{ /// - public partial class {migrationName} : Migration + public partial class _{migrationId} : Migration {{ /// protected override void Up(MigrationBuilder migrationBuilder) diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/MigrationContext.cs b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/MigrationContext.cs index c347a9cc590..dd40f9e55a6 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/MigrationContext.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/MigrationContext.cs @@ -44,6 +44,6 @@ protected void RemoveVariableModelAnnotations(ModelBuilder modelBuilder) model.RemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy); } - public abstract string GetExpectedMigrationCode(string migrationName, string rootNamespace); + public abstract string GetExpectedMigrationCode(string migrationId, string rootNamespace); public abstract string GetExpectedSnapshotCode(string rootNamespace, string migrationId); } diff --git a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs index 94edd2ca7d3..741c61dc3b6 100644 --- a/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs +++ b/test/EFCore.SqlServer.HierarchyId.Tests/TestModels/Migrations/TypedArraySeedContext.cs @@ -41,7 +41,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); } - public override string GetExpectedMigrationCode(string migrationName, string rootNamespace) + public override string GetExpectedMigrationCode(string migrationId, string rootNamespace) => $@"using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.SqlServer.Types; @@ -52,7 +52,7 @@ public override string GetExpectedMigrationCode(string migrationName, string roo namespace {rootNamespace}.Migrations {{ /// - public partial class {migrationName} : Migration + public partial class _{migrationId} : Migration {{ /// protected override void Up(MigrationBuilder migrationBuilder) From 9c8f56ace7bd4cd238a75ca9b9f14f46f40e5eda Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Wed, 4 Mar 2026 12:54:59 -0800 Subject: [PATCH 5/5] Update test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Migrations/Design/MigrationScaffolderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs index 36bdd0f248f..e95faedd9a9 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -52,7 +52,7 @@ public void ScaffoldMigration_can_override_namespace() } [ConditionalFact] - public void ScaffoldMigration_appends_timestamp_to_type_name() + public void ScaffoldMigration_uses_migration_id_as_type_name() { var scaffolder = CreateMigrationScaffolder();