diff --git a/entity-framework/core/performance/advanced-performance-topics.md b/entity-framework/core/performance/advanced-performance-topics.md
index bcd662ae1f..c39b4bfe67 100644
--- a/entity-framework/core/performance/advanced-performance-topics.md
+++ b/entity-framework/core/performance/advanced-performance-topics.md
@@ -295,6 +295,7 @@ Compiled models have some limitations:
* [Global query filters are not supported](https://github.com/dotnet/efcore/issues/24897).
* [Lazy loading and change-tracking proxies are not supported](https://github.com/dotnet/efcore/issues/24902).
+* Value converters that reference private methods are not supported. Make referenced methods public or internal instead.
* [The model must be manually synchronized by regenerating it any time the model definition or configuration change](https://github.com/dotnet/efcore/issues/24894).
* Custom IModelCacheKeyFactory implementations are not supported. However, you can compile multiple models and load the appropriate one as needed.
diff --git a/entity-framework/core/what-is-new/ef-core-10.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-10.0/breaking-changes.md
index 070c493be1..5f3f2292d6 100644
--- a/entity-framework/core/what-is-new/ef-core-10.0/breaking-changes.md
+++ b/entity-framework/core/what-is-new/ef-core-10.0/breaking-changes.md
@@ -24,6 +24,9 @@ This page documents API and behavior changes that have the potential to break ex
|:--------------------------------------------------------------------------------------------------------------- | -----------|
| [SQL Server json data type used by default on Azure SQL and compatibility level 170](#sqlserver-json-data-type) | Low |
| [ExecuteUpdateAsync now accepts a regular, non-expression lambda](#ExecuteUpdateAsync-lambda) | Low |
+| [Complex type column names are now uniquified](#complex-type-column-uniquification) | Low |
+| [Nested complex type properties use full path in column names](#nested-complex-type-column-names) | Low |
+| [IDiscriminatorPropertySetConvention signature changed](#discriminator-convention-signature) | Low |
## Low-impact changes
@@ -178,6 +181,93 @@ await context.Blogs.ExecuteUpdateAsync(s =>
});
```
+
+
+### Complex type column names are now uniquified
+
+[Tracking Issue #4970](https://github.com/dotnet/EntityFramework.Docs/issues/4970)
+
+#### Old behavior
+
+Previously, when mapping complex types to table columns, if multiple properties in different complex types had the same column name, they would silently share the same column.
+
+#### New behavior
+
+Starting with EF Core 10.0, complex type column names are uniquified by appending a number at the end if another column with the same name exists on the table.
+
+#### Why
+
+This prevents data corruption that could occur when multiple properties are unintentionally mapped to the same column.
+
+#### Mitigations
+
+If you need multiple properties to share the same column, configure them explicitly:
+
+```c#
+modelBuilder.Entity(b =>
+{
+ b.ComplexProperty(c => c.ShippingAddress, p => p.Property(a => a.Street).HasColumnName("Street"));
+ b.ComplexProperty(c => c.BillingAddress, p => p.Property(a => a.Street).HasColumnName("Street"));
+});
+```
+
+
+
+### Nested complex type properties use full path in column names
+
+#### Old behavior
+
+Previously, properties on nested complex types were mapped to columns using just the declaring type name. For example, `EntityType.Complex.NestedComplex.Property` was mapped to column `NestedComplex_Property`.
+
+#### New behavior
+
+Starting with EF Core 10.0, properties on nested complex types use the full path to the property as part of the column name. For example, `EntityType.Complex.NestedComplex.Property` is now mapped to column `Complex_NestedComplex_Property`.
+
+#### Why
+
+This provides better column name uniqueness and makes it clearer which property maps to which column.
+
+#### Mitigations
+
+If you need to maintain the old column names, configure them explicitly:
+
+```c#
+modelBuilder.Entity()
+ .ComplexProperty(e => e.Complex)
+ .ComplexProperty(o => o.NestedComplex)
+ .Property(c => c.Property)
+ .HasColumnName("NestedComplex_Property");
+```
+
+
+
+### IDiscriminatorPropertySetConvention signature changed
+
+#### Old behavior
+
+Previously, `IDiscriminatorPropertySetConvention.ProcessDiscriminatorPropertySet` took `IConventionEntityTypeBuilder` as a parameter.
+
+#### New behavior
+
+Starting with EF Core 10.0, the method signature changed to take `IConventionTypeBaseBuilder` instead of `IConventionEntityTypeBuilder`.
+
+#### Why
+
+This change allows the convention to work with both entity types and complex types.
+
+#### Mitigations
+
+Update your custom convention implementations to use the new signature:
+
+```c#
+public virtual void ProcessDiscriminatorPropertySet(
+ IConventionTypeBaseBuilder typeBaseBuilder, // Changed from IConventionEntityTypeBuilder
+ string name,
+ Type type,
+ MemberInfo memberInfo,
+ IConventionContext context)
+```
+
## Microsoft.Data.Sqlite breaking changes
diff --git a/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md
index 44f38c5155..459cea6c47 100644
--- a/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md
+++ b/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md
@@ -29,6 +29,7 @@ EF Core 9 targets .NET 8. This means that existing applications that target .NET
| [Exception is thrown when applying migrations in an explicit transaction](#migrations-transaction) | High |
| [`Microsoft.EntityFrameworkCore.Design` not found when using EF tools](#tools-design) | Medium |
| [`EF.Functions.Unhex()` now returns `byte[]?`](#unhex) | Low |
+| [Compiled models now reference value converter methods directly](#compiled-model-private-methods) | Low |
| [SqlFunctionExpression's nullability arguments' arity validated](#sqlfunctionexpression-nullability) | Low |
| [`ToString()` method now returns empty string for `null` instances](#nullable-tostring) | Low |
| [Shared framework dependencies were updated to 9.0.x](#shared-framework-dependencies) | Low |
@@ -228,6 +229,41 @@ var binaryData = await context.Blogs.Select(b => EF.Functions.Unhex(b.HexString)
Otherwise, add runtime checks for null on the return value of Unhex().
+
+
+### Compiled models now reference value converter methods directly
+
+[Tracking Issue #35033](https://github.com/dotnet/efcore/issues/35033)
+
+#### Old behavior
+
+Previously, when using value converters with compiled models (using `dotnet ef dbcontext optimize`), EF would reference the converter type and everything worked correctly.
+
+```c#
+public sealed class BooleanToCharConverter() : ValueConverter(v => ConvertToChar(v), v => ConvertToBoolean(v))
+{
+ public static readonly BooleanToCharConverter Default = new();
+
+ private static char ConvertToChar(bool value) // Private method
+ => value ? 'Y' : 'N';
+
+ private static bool ConvertToBoolean(char value) // Private method
+ => value == 'Y';
+}
+```
+
+#### New behavior
+
+Starting with EF Core 9.0, EF generates code that directly references the conversion methods themselves. If these methods are private, compilation will fail.
+
+#### Why
+
+This change was necessary to support NativeAOT.
+
+#### Mitigations
+
+Make the methods referenced by value converters public or internal instead of private.
+
### SqlFunctionExpression's nullability arguments' arity validated