From cb56f95c0543ac9aed604ea6dd1e3eeb7c7a09bb Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 00:56:02 +0000
Subject: [PATCH 1/7] Initial plan
From c3d658fdc9cab4198d4eacf4181a1d48af4c078e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 01:10:14 +0000
Subject: [PATCH 2/7] Move IOperationReporter, ISnapshotModelProcessor,
SnapshotModelProcessor to EFCore.Relational
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
---
src/EFCore.Design/Properties/DesignStrings.Designer.cs | 8 --------
src/EFCore.Design/Properties/DesignStrings.resx | 3 ---
.../Design/Internal/IOperationReporter.cs | 0
.../Migrations/Internal/ISnapshotModelProcessor.cs | 0
.../Migrations/Internal/SnapshotModelProcessor.cs | 7 ++++++-
.../Properties/RelationalStrings.Designer.cs | 8 ++++++++
src/EFCore.Relational/Properties/RelationalStrings.resx | 3 +++
.../Migrations/Design/SnapshotModelProcessorTest.cs | 5 +++--
.../EFCore.Specification.Tests.csproj | 1 +
9 files changed, 21 insertions(+), 14 deletions(-)
rename src/{EFCore.Design => EFCore.Relational}/Design/Internal/IOperationReporter.cs (100%)
rename src/{EFCore.Design => EFCore.Relational}/Migrations/Internal/ISnapshotModelProcessor.cs (100%)
rename src/{EFCore.Design => EFCore.Relational}/Migrations/Internal/SnapshotModelProcessor.cs (96%)
diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs
index 33d3bdbf9e1..265ebee84ee 100644
--- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs
+++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs
@@ -517,14 +517,6 @@ public static string MSBuildWorkspaceFailure(object? kind, object? message)
GetString("MSBuildWorkspaceFailure", nameof(kind), nameof(message)),
kind, message);
- ///
- /// The annotation '{annotationName}' was specified twice with potentially different values. Specifying the same annotation multiple times for different providers is no longer supported. Review the generated Migration to ensure it is correct and, if necessary, edit the Migration to fix any issues.
- ///
- public static string MultipleAnnotationConflict(object? annotationName)
- => string.Format(
- GetString("MultipleAnnotationConflict", nameof(annotationName)),
- annotationName);
-
///
/// More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
///
diff --git a/src/EFCore.Design/Properties/DesignStrings.resx b/src/EFCore.Design/Properties/DesignStrings.resx
index 3153de94ed4..c3777c2da09 100644
--- a/src/EFCore.Design/Properties/DesignStrings.resx
+++ b/src/EFCore.Design/Properties/DesignStrings.resx
@@ -319,9 +319,6 @@ Change your target project to the migrations project by using the Package Manage
MSBuild Workspace failure: {kind} - {message}
-
- The annotation '{annotationName}' was specified twice with potentially different values. Specifying the same annotation multiple times for different providers is no longer supported. Review the generated Migration to ensure it is correct and, if necessary, edit the Migration to fix any issues.
-
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
diff --git a/src/EFCore.Design/Design/Internal/IOperationReporter.cs b/src/EFCore.Relational/Design/Internal/IOperationReporter.cs
similarity index 100%
rename from src/EFCore.Design/Design/Internal/IOperationReporter.cs
rename to src/EFCore.Relational/Design/Internal/IOperationReporter.cs
diff --git a/src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs b/src/EFCore.Relational/Migrations/Internal/ISnapshotModelProcessor.cs
similarity index 100%
rename from src/EFCore.Design/Migrations/Internal/ISnapshotModelProcessor.cs
rename to src/EFCore.Relational/Migrations/Internal/ISnapshotModelProcessor.cs
diff --git a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs b/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
similarity index 96%
rename from src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs
rename to src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
index c46bb2bf93b..53145af9ad2 100644
--- a/src/EFCore.Design/Migrations/Internal/SnapshotModelProcessor.cs
+++ b/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.EntityFrameworkCore.Design.Internal;
+using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
@@ -52,8 +53,10 @@ public SnapshotModelProcessor(
public virtual IModel? Process(IReadOnlyModel? model, bool resetVersion = false)
{
if (model == null
+#pragma warning disable EF1001 // Internal EF Core API usage.
|| model is not Model mutableModel
|| mutableModel.IsReadOnly)
+#pragma warning restore EF1001 // Internal EF Core API usage.
{
return null;
}
@@ -85,7 +88,9 @@ public SnapshotModelProcessor(
mutableModel.RemoveAnnotation("ChangeDetector.SkipDetectChanges");
if (resetVersion)
{
+#pragma warning disable EF1001 // Internal EF Core API usage.
mutableModel.SetProductVersion(ProductInfo.GetVersion());
+#pragma warning restore EF1001 // Internal EF Core API usage.
}
return _modelRuntimeInitializer.Initialize((IModel)model, designTime: true, validationLogger: null);
@@ -160,7 +165,7 @@ private void ProcessElement(IReadOnlyAnnotatable? metadata, string version)
else if (!Equals(duplicate.Value, annotation.Value))
{
_operationReporter.WriteWarning(
- DesignStrings.MultipleAnnotationConflict(stripped[1..]));
+ RelationalStrings.MultipleAnnotationConflict(stripped[1..]));
}
}
}
diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
index 96e6ac2c2dd..9b38da270ab 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
+++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
@@ -1573,6 +1573,14 @@ public static string ModificationCommandInvalidEntityStateSensitive(object? enti
GetString("ModificationCommandInvalidEntityStateSensitive", nameof(entityType), nameof(keyValues), nameof(entityState)),
entityType, keyValues, entityState);
+ ///
+ /// The annotation '{annotationName}' was specified twice with potentially different values. Specifying the same annotation multiple times for different providers is no longer supported. Review the generated Migration to ensure it is correct and, if necessary, edit the Migration to fix any issues.
+ ///
+ public static string MultipleAnnotationConflict(object? annotationName)
+ => string.Format(
+ GetString("MultipleAnnotationConflict", nameof(annotationName)),
+ annotationName);
+
///
/// Entity type '{entityType}' is mapped to multiple columns with name '{columnName}', and one of them is configured as a JSON column. Assign different names to the columns.
///
diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx
index cd3ad37927f..de4225de935 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.resx
+++ b/src/EFCore.Relational/Properties/RelationalStrings.resx
@@ -1049,6 +1049,9 @@
Cannot save changes for an entity of type '{entityType}' with primary key values {keyValues} in state '{entityState}'. This may indicate a bug in Entity Framework, file an issue at https://aka.ms/efcorefeedback.
+
+ The annotation '{annotationName}' was specified twice with potentially different values. Specifying the same annotation multiple times for different providers is no longer supported. Review the generated Migration to ensure it is correct and, if necessary, edit the Migration to fix any issues.
+
Entity type '{entityType}' is mapped to multiple columns with name '{columnName}', and one of them is configured as a JSON column. Assign different names to the columns.
diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
index d892bf13d42..0b5feec7842 100644
--- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
+++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.EntityFrameworkCore.Design.Internal;
+using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Ownership;
@@ -89,7 +90,7 @@ public void Warns_for_conflicting_annotations()
var (level, message) = reporter.Messages.Single();
Assert.Equal(LogLevel.Warning, level);
- Assert.Equal(DesignStrings.MultipleAnnotationConflict("DefaultSchema"), message);
+ Assert.Equal(RelationalStrings.MultipleAnnotationConflict("DefaultSchema"), message);
Assert.Equal(2, model.GetAnnotations().Count());
var actual = (string)model["Relational:DefaultSchema"];
@@ -112,7 +113,7 @@ public void Warns_for_conflicting_annotations_one_relational()
var (level, message) = reporter.Messages.Single();
Assert.Equal(LogLevel.Warning, level);
- Assert.Equal(DesignStrings.MultipleAnnotationConflict("DefaultSchema"), message);
+ Assert.Equal(RelationalStrings.MultipleAnnotationConflict("DefaultSchema"), message);
Assert.Equal(2, model.GetAnnotations().Count());
var actual = (string)model["Relational:DefaultSchema"];
diff --git a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
index f0f6767cc31..c5298d9eede 100644
--- a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
+++ b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
@@ -54,6 +54,7 @@
+
From cb6b0c887c28749c4faf38a91d2973c054d529d6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 01:15:05 +0000
Subject: [PATCH 3/7] Update ef tool to link IOperationReporter from its new
location
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
---
src/ef/ef.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ef/ef.csproj b/src/ef/ef.csproj
index 4c3d18cda35..c34cfc87c2b 100644
--- a/src/ef/ef.csproj
+++ b/src/ef/ef.csproj
@@ -21,7 +21,7 @@
-
+
From 252164aae02c9fb193ec616b16338c95c36a81bc Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 01:15:58 +0000
Subject: [PATCH 4/7] Fix trailing whitespace and update migrations skill
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
---
.agents/skills/migrations/SKILL.md | 2 +-
.../Migrations/Internal/SnapshotModelProcessor.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.agents/skills/migrations/SKILL.md b/.agents/skills/migrations/SKILL.md
index 96e5223a200..68d6f057c3e 100644
--- a/.agents/skills/migrations/SKILL.md
+++ b/.agents/skills/migrations/SKILL.md
@@ -15,7 +15,7 @@ user-invocable: false
## Model Snapshot
- Model snapshots use `typeof(Dictionary)` (property bag format), not the actual CLR type. When examining the `ClrType` in a snapshot, don't assume it matches the real entity type.
-- `SnapshotModelProcessor.Process()` is used at design-time to fixup older model snapshots for backward compatibility.
+- `SnapshotModelProcessor.Process()` is used at design-time to fixup older model snapshots for backward compatibility. It lives in EFCore.Relational (namespace `Microsoft.EntityFrameworkCore.Migrations.Internal`) so relational providers can register a custom `ISnapshotModelProcessor`; the default is registered (via `TryAdd`) in `DesignTimeServiceCollectionExtensions`.
## Testing
diff --git a/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs b/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
index 53145af9ad2..9c3e9580263 100644
--- a/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
+++ b/src/EFCore.Relational/Migrations/Internal/SnapshotModelProcessor.cs
@@ -122,7 +122,7 @@ private void ProcessComplexProperties(IReadOnlyTypeBase typeBase, string version
foreach (var complexProperty in typeBase.GetComplexProperties())
{
ProcessElement(complexProperty, version);
-
+
if (complexProperty is IMutableComplexProperty mutableComplexProperty)
{
UpdateComplexPropertyNullability(mutableComplexProperty, version);
From 46528c855cbd43d291d4a50d631180ea476e608b Mon Sep 17 00:00:00 2001
From: Andriy Svyryd
Date: Wed, 10 Jun 2026 19:12:44 -0700
Subject: [PATCH 5/7] Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
.../Migrations/Design/SnapshotModelProcessorTest.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
index 0b5feec7842..7d1bc8927bc 100644
--- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
+++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.EntityFrameworkCore.Design.Internal;
-using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Ownership;
From 0cc4d2c49ab8f47b051692a4507169b7df0d41c7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 02:23:21 +0000
Subject: [PATCH 6/7] Revert migrations skill note update
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
---
.agents/skills/migrations/SKILL.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.agents/skills/migrations/SKILL.md b/.agents/skills/migrations/SKILL.md
index 68d6f057c3e..96e5223a200 100644
--- a/.agents/skills/migrations/SKILL.md
+++ b/.agents/skills/migrations/SKILL.md
@@ -15,7 +15,7 @@ user-invocable: false
## Model Snapshot
- Model snapshots use `typeof(Dictionary)` (property bag format), not the actual CLR type. When examining the `ClrType` in a snapshot, don't assume it matches the real entity type.
-- `SnapshotModelProcessor.Process()` is used at design-time to fixup older model snapshots for backward compatibility. It lives in EFCore.Relational (namespace `Microsoft.EntityFrameworkCore.Migrations.Internal`) so relational providers can register a custom `ISnapshotModelProcessor`; the default is registered (via `TryAdd`) in `DesignTimeServiceCollectionExtensions`.
+- `SnapshotModelProcessor.Process()` is used at design-time to fixup older model snapshots for backward compatibility.
## Testing
From 09e2384a53fc70b02b8618a9d1a68a4714158c26 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 11 Jun 2026 19:49:24 +0000
Subject: [PATCH 7/7] Update EFCore.Relational API baseline with
MultipleAnnotationConflict
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
---
src/EFCore.Relational/EFCore.Relational.baseline.json | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/EFCore.Relational/EFCore.Relational.baseline.json b/src/EFCore.Relational/EFCore.Relational.baseline.json
index 78998352236..e37eca0a3a6 100644
--- a/src/EFCore.Relational/EFCore.Relational.baseline.json
+++ b/src/EFCore.Relational/EFCore.Relational.baseline.json
@@ -16710,6 +16710,9 @@
{
"Member": "static string ModificationCommandInvalidEntityStateSensitive(object? entityType, object? keyValues, object? entityState);"
},
+ {
+ "Member": "static string MultipleAnnotationConflict(object? annotationName);"
+ },
{
"Member": "static string MultipleColumnsWithSameJsonContainerName(object? entityType, object? columnName);"
},