From 8336d18cecb5bc65219a5cc16ea76b38833c1b1b Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Wed, 6 Oct 2021 17:40:57 -0700 Subject: [PATCH 1/2] Fixes #3103 Fixes #2859 Fixes #3289 Fixes #3340 --- .../ef-core-6.0/breaking-changes.md | 100 ++++++++++++++++++ .../FluentAPI/CheckConstraint.cs | 2 +- .../IndexesAndConstraints.csproj | 6 +- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md index bc09b1f8b6..e0e55d5f3a 100644 --- a/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md +++ b/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md @@ -14,12 +14,42 @@ The following API and behavior changes have the potential to break existing appl | **Breaking change** | **Impact** | |:--------------------------------------------------------------------------------------------------------------------------------------|------------| +| [Changing the owner of an owned entity now throws an exception](#owned-reparenting) | Medium | | [Cleaned up mapping between DeleteBehavior and ON DELETE values](#on-delete) | Low | | [Removed last ORDER BY when joining for collections](#last-order-by) | Low | | [DbSet no longer implements IAsyncEnumerable](#dbset-iasyncenumerable) | Low | +| [Check constraint name uniqueness is now validated](#unique-check-constraints) | Low | +| [Added IReadOnly Metadata interfaces and removed extension methods](#ireadonly-metadata) | Low | | [Some Singleton services are now Scoped](#query-services) | Low | | [New caching API for extensions that add or replace services](#extensions-caching) | Low | | [New snapshot model initialization procedure](#snapshot-initialization) | Low | +| [`OwnedNavigationBuilder.HasIndex` returns a different type now](#owned-index) | Low | + +## Medium-impact changes + + + +### Changing the owner of an owned entity now throws an exception + +[Tracking Issue #4073](https://github.com/dotnet/efcore/issues/4073) + +#### Old behavior + +It was possible to reassign an owned entity to a different owner entity. + +#### New behavior + +This action will now throw an exception: + +> The property '{entityType}.{property}' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key, first delete the dependent and invoke 'SaveChanges', and then associate the dependent with the new principal. + +#### Why + +Even though we don't require key properties to exist on an owned type, EF will still create shadow properties to be used as the primary key and the foreign key pointing to the owner. When the owner entity is changed it causes the values of the foreign key on the owned entity to change and since they are also used as the primary key this results in the entity identity to change. This isn't fully supported in EF Core yet and was only conditionally allowed for owned entities which sometimes resulted in the internal state to become inconsistent. + +#### Mitigations + +Instead of assigning the same owned instance to a new owner you can assign a copy and delete the old one. ## Low-impact changes @@ -132,6 +162,54 @@ The vast majority of `DbSet` usages will continue to work as-is, since they comp If you need to refer to a as an , call to explicitly cast it. + + +### Check constraint name uniqueness is now validated + +[Tracking Issue #25061](https://github.com/dotnet/efcore/issues/25061) + +#### Old behavior + +Check constraints with the same name were allowed to be declared and used. + +#### New behavior + +Explicitly configuring two check constraints with the same name will now result in an exception. Check constraints created by a convention will be assigned a unique name. + +#### Why + +Most databases don't allow two check constraints with the same name to be created on the same table and some require them to be unique even across tables. This would result in exception being thrown when applying a migration. + +#### Mitigations + +In some cases valid check constraint names might be different due to this change. To specify the desired name explicitly call : + +```csharp +modelBuilder.Entity().HasCheckConstraint("CK_Id", "Id > 0", c => c.HasName("CK_MyEntity_Id")); +``` + + + +### Added IReadOnly Metadata interfaces and removed extension methods + +[Tracking Issue #19213](https://github.com/dotnet/efcore/issues/19213) + +#### Old behavior + +There were three sets of metadata interfaces: , and as well as extension methods. + +#### New behavior + +A new set of `IReadOnly` interfaces has been added, e.g. . And extension methods that were previously defined for the metadata interfaces have been converted to default interface methods. + +#### Why + +Default interface methods allow the implementation to be overridden, this is leveraged by the new run-time model implementation to offer better performance. + +#### Mitigations + +These changes shouldn't affect most code, however if you were using the extension methods vis the static invocation syntax it needs to be converted to instance invocation syntax. + ### Some Singleton services are now Scoped @@ -234,3 +312,25 @@ var hasDifferences = context.GetService().HasDifferences snapshotModel?.GetRelationalModel(), context.GetService().Model.GetRelationalModel()); ``` + + + +### `OwnedNavigationBuilder.HasIndex` returns a different type now + +[Tracking Issue #24005](https://github.com/dotnet/efcore/issues/24005) + +#### Old behavior + +In EF Core 5, returned `IndexBuilder` where `TEntity` is the owner type. + +#### New behavior + +Now returned `IndexBuilder` where `TDependentEntity` is the owned type. + +#### Why + +The returned builder object wasn't typed correctly. + +#### Mitigations + +Recompiling your assembly against the latest version of EF Core will be enough to fix any issues caused by this change. diff --git a/samples/core/Modeling/IndexesAndConstraints/FluentAPI/CheckConstraint.cs b/samples/core/Modeling/IndexesAndConstraints/FluentAPI/CheckConstraint.cs index 47e1ab05f3..03488361cf 100644 --- a/samples/core/Modeling/IndexesAndConstraints/FluentAPI/CheckConstraint.cs +++ b/samples/core/Modeling/IndexesAndConstraints/FluentAPI/CheckConstraint.cs @@ -10,7 +10,7 @@ internal class MyContext : DbContext protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() - .HasCheckConstraint("CK_Prices", "[Price] > [DiscountedPrice]"); + .HasCheckConstraint("CK_Prices", "[Price] > [DiscountedPrice]", c => c.HasName("CK_Product_Prices")); } #endregion } diff --git a/samples/core/Modeling/IndexesAndConstraints/IndexesAndConstraints.csproj b/samples/core/Modeling/IndexesAndConstraints/IndexesAndConstraints.csproj index 7d93aba15b..502728be9e 100644 --- a/samples/core/Modeling/IndexesAndConstraints/IndexesAndConstraints.csproj +++ b/samples/core/Modeling/IndexesAndConstraints/IndexesAndConstraints.csproj @@ -1,14 +1,14 @@ - + Exe - net5.0 + net6.0 EFModeling.IndexesAndConstraints EFModeling.IndexesAndConstraints - + From 80e85116f67065f36d5ce801acdd10c250f3ecb6 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Thu, 7 Oct 2021 16:31:05 -0700 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Shay Rojansky --- .../what-is-new/ef-core-6.0/breaking-changes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md index e0e55d5f3a..7f9aa0f618 100644 --- a/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md +++ b/entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md @@ -45,7 +45,7 @@ This action will now throw an exception: #### Why -Even though we don't require key properties to exist on an owned type, EF will still create shadow properties to be used as the primary key and the foreign key pointing to the owner. When the owner entity is changed it causes the values of the foreign key on the owned entity to change and since they are also used as the primary key this results in the entity identity to change. This isn't fully supported in EF Core yet and was only conditionally allowed for owned entities which sometimes resulted in the internal state to become inconsistent. +Even though we don't require key properties to exist on an owned type, EF will still create shadow properties to be used as the primary key and the foreign key pointing to the owner. When the owner entity is changed it causes the values of the foreign key on the owned entity to change, and since they are also used as the primary key this results in the entity identity to change. This isn't yet fully supported in EF Core and was only conditionally allowed for owned entities, sometimes resulting in the internal state becoming inconsistent. #### Mitigations @@ -170,19 +170,19 @@ If you need to refer to a as an < #### Old behavior -Check constraints with the same name were allowed to be declared and used. +Check constraints with the same name were allowed to be declared and used on the same table. #### New behavior -Explicitly configuring two check constraints with the same name will now result in an exception. Check constraints created by a convention will be assigned a unique name. +Explicitly configuring two check constraints with the same name on the same table will now result in an exception. Check constraints created by a convention will be assigned a unique name. #### Why -Most databases don't allow two check constraints with the same name to be created on the same table and some require them to be unique even across tables. This would result in exception being thrown when applying a migration. +Most databases don't allow two check constraints with the same name to be created on the same table, and some require them to be unique even across tables. This would result in exception being thrown when applying a migration. #### Mitigations -In some cases valid check constraint names might be different due to this change. To specify the desired name explicitly call : +In some cases, valid check constraint names might be different due to this change. To specify the desired name explicitly, call : ```csharp modelBuilder.Entity().HasCheckConstraint("CK_Id", "Id > 0", c => c.HasName("CK_MyEntity_Id")); @@ -200,7 +200,7 @@ There were three sets of metadata interfaces: . And extension methods that were previously defined for the metadata interfaces have been converted to default interface methods. +A new set of `IReadOnly` interfaces has been added, e.g. . Extension methods that were previously defined for the metadata interfaces have been converted to default interface methods. #### Why @@ -208,7 +208,7 @@ Default interface methods allow the implementation to be overridden, this is lev #### Mitigations -These changes shouldn't affect most code, however if you were using the extension methods vis the static invocation syntax it needs to be converted to instance invocation syntax. +These changes shouldn't affect most code. However, if you were using the extension methods via the static invocation syntax, it would need to be converted to instance invocation syntax. @@ -325,7 +325,7 @@ In EF Core 5, returned `IndexBuilder` where `TDependentEntity` is the owned type. + now returns `IndexBuilder`, where `TDependentEntity` is the owned type. #### Why