Skip to content

Commit 640acf0

Browse files
committed
Updates to breaking changes
Fixes #4608 Part of #4538 Fixes #4315 Fixes #4257 Fixes #4655 Fixes #4654
1 parent 66cbb8f commit 640acf0

File tree

3 files changed

+151
-5
lines changed

3 files changed

+151
-5
lines changed

entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ EF Core 6.0 targets .NET 6. Applications targeting older .NET, .NET Core, and .N
4444
| [Default table mapping is not removed when the entity is mapped to a table-valued function](#tvf-default-mapping) | Low |
4545
| [dotnet-ef targets .NET 6](#dotnet-ef) | Low |
4646
| [`IModelCacheKeyFactory` implementations may need to be updated to handle design-time caching](#model-cache-key) | Low |
47+
| [`NavigationBaseIncludeIgnored` is now an error by default](#ignored-navigation) | Low |
4748

4849
\* These changes are of particular interest to authors of database providers and extensions.
4950

@@ -944,3 +945,32 @@ public object Create(DbContext context, bool designTime)
944945
? (context.GetType(), dynamicContext.UseIntProperty, designTime)
945946
: (object)context.GetType();
946947
```
948+
949+
The navigation '{navigation}' was ignored from 'Include' in the query since the fix-up will automatically populate it. If any further navigations are specified in 'Include' afterwards then they will be ignored. Walking back include tree is not allowed.
950+
951+
<a name="ignored-navigation"></a>
952+
953+
### `NavigationBaseIncludeIgnored` is now an error by default
954+
955+
[Tracking Issue #4315](https://github.com/dotnet/EntityFramework.Docs/issues/4315)
956+
957+
#### Old behavior
958+
959+
The event `CoreEventId.NavigationBaseIncludeIgnored` was logged as a warning by default.
960+
961+
#### New behavior
962+
963+
The event `CoreEventId.NavigationBaseIncludeIgnored` was logged as an error by default and causes an exception to be thrown.
964+
965+
#### Why
966+
967+
These query patterns are not allowed, so EF Core now throws to indicate that the queries should be updated.
968+
969+
#### Mitigations
970+
971+
The old behavior can be restored by configuring the event as a warning. For example:
972+
973+
```csharp
974+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
975+
=> optionsBuilder.ConfigureWarnings(b => b.Warn(CoreEventId.NavigationBaseIncludeIgnored));
976+
```

entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,21 @@ The performance improvements linked to the new method are significant enough tha
131131

132132
#### Mitigations
133133

134-
You can let EF Core know that the target table has a trigger; doing so will revert to the previous, less efficient technique. This can be done by configuring the corresponding entity type as follows:
134+
If the target table has a trigger, then you can let EF Core know this, and EF will revert to the previous, less efficient technique. This can be done by configuring the corresponding entity type as follows:
135135

136136
[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=TriggerConfiguration&highlight=4)]
137137

138-
Note that doing this doesn't actually make EF Core create or manage the trigger in any way - it currently only informs EF Core that triggers are present on the table. As a result, any trigger name can be used, and this can also be used if an unsupported computed column is in use (regardless of triggers).
138+
Note that doing this doesn't actually make EF Core create or manage the trigger in any way - it currently only informs EF Core that triggers are present on the table. As a result, any trigger name can be used.
139+
140+
Specifying a trigger can be used to revert the old behavior, _even if there isn't actually a trigger in the table_. However, starting with EF Core 8.0, the use or not of the "OUTPUT" clause can configured explicitly, regardless of triggers. For example:
141+
142+
```csharp
143+
protected override void OnModelCreating(ModelBuilder modelBuilder)
144+
{
145+
modelBuilder.Entity<Blog>()
146+
.ToTable(tb => tb.UseSqlOutputClause(false));
147+
}
148+
```
139149

140150
If most or all of your tables have triggers, you can opt out of using the newer, efficient technique for all your model's tables by using the following model building convention:
141151

@@ -167,7 +177,17 @@ The simplifications and performance improvements linked to the new method are si
167177

168178
#### Mitigations
169179

170-
In EF Core 8.0, a mechanism will be introduced that will allow specifying whether to use the new mechanism on a table-by-table basis. With EF Core 7.0, it's possible to revert to the old mechanism for the entire application by inserting the following code in your context configuration:
180+
In EF Core 8.0, the `UseSqlReturningClause` method has been introduced to explicitly revert back to the older, less efficient SQL. For example:
181+
182+
```csharp
183+
protected override void OnModelCreating(ModelBuilder modelBuilder)
184+
{
185+
modelBuilder.Entity<Blog>()
186+
.ToTable(tb => tb.UseSqlReturningClause(false));
187+
}
188+
```
189+
190+
If you are still using EF Core 7.0, then it's possible to revert to the old mechanism for the entire application by inserting the following code in your context configuration:
171191

172192
```c#
173193
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
@@ -493,11 +513,11 @@ Query or attach entities before marking entities as `Deleted`, or manually set n
493513

494514
#### Old behavior
495515

496-
In EF Core 6.0, using the Azure Cosmos DB <xref:Microsoft.EntityFrameworkCore.CosmosQueryableExtensions.FromSqlRaw%2A> extension method when using a relational provider, or the relational <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw%2A> extension method when using the Azure Cosmos DB provider could silently fail.
516+
In EF Core 6.0, using the Azure Cosmos DB <xref:Microsoft.EntityFrameworkCore.CosmosQueryableExtensions.FromSqlRaw%2A> extension method when using a relational provider, or the relational <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw%2A> extension method when using the Azure Cosmos DB provider could silently fail. Likewise, using relational methods on the in-memory provider is a silent no-op.
497517

498518
#### New behavior
499519

500-
Starting with EF Core 7.0, using the wrong extension method will throw an exception.
520+
Starting with EF Core 7.0, using an extension method designed for one provider on a different provider will throw an exception.
501521

502522
#### Why
503523

entity-framework/core/what-is-new/ef-core-8.0/breaking-changes.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ EF Core 8 targets .NET 8. Applications targeting older .NET, .NET Core, and .NET
3131
| [ExcludeFromMigrations no longer excludes other tables in a TPC hierarchy](#exclude-from-migrations) | Low |
3232
| [Non-shadow integer keys are persisted to Cosmos documents](#persist-to-cosmos) | Low |
3333
| [Relational model is generated in the compiled model](#compiled-relational-model) | Low |
34+
| [Scaffolding may generate different navigation names](#navigation-names) | Low |
35+
| [Discriminators now have a max length](#discriminators) | Low |
36+
| [SQL Server key values are compared case-insensitively](#casekeys) | Low |
3437

3538
## High-impact changes
3639

@@ -437,3 +440,96 @@ This was done to further improve startup time.
437440
#### Mitigations
438441

439442
Edit the generated `*ModelBuilder.cs` file and remove the line `AddRuntimeAnnotation("Relational:RelationalModel", CreateRelationalModel());` as well as the method `CreateRelationalModel()`.
443+
444+
<a name="navigation-names"></a>
445+
446+
### Scaffolding may generate different navigation names
447+
448+
[Tracking Issue #27832](https://github.com/dotnet/efcore/issues/27832)
449+
450+
#### Old behavior
451+
452+
Previously when scaffolding a `DbContext` and entity types from an existing database, the navigation names for relationships were sometimes derived from a common prefix of multiple foreign key column names.
453+
454+
#### New behavior
455+
456+
Starting with EF Core 8.0, common prefixes of column names from a composite foreign key are no longer used to generate navigation names.
457+
458+
#### Why
459+
460+
This is an obscure naming rule which sometimes generates very poor names like, `S`, `Student_`, or even just `_`. Without this rule, strange names are no longer generated, and the naming conventions for navigations are also made simpler, thereby making it easier to understand and predict which names will be generated.
461+
462+
#### Mitigations
463+
464+
The [EF Core Power Tools](https://github.com/ErikEJ/EFCorePowerTools/issues/2143) have an option to keep generating navigations in the old way. Alternatively, the code generated can be fully customized using [T4 templates](xref:core/managing-schemas/scaffolding/templates). This can be used to example the foreign key properties of scaffolding relationships and use whatever rule is appropriate for your code to generate the navigation names you need.
465+
466+
<a name="discriminators"></a>
467+
468+
### Discriminators now have a max length
469+
470+
[Tracking Issue #10691](https://github.com/dotnet/efcore/issues/10691)
471+
472+
#### Old behavior
473+
474+
Previously, discriminator columns created for [TPH inheritance mapping](xref:core/modeling/inheritance) were configured as `nvarchar(max)` on SQL Server/Azure SQL, or the equivalent unbounded string type on other databases.
475+
476+
#### New behavior
477+
478+
Starting with EF Core 8.0, discriminator columns are created with a max length that covers all the known discriminator values. If the discriminator column is constrained in some way--for example, as part of an index--then the `AlterColumn` created by Migrations may fail.
479+
480+
#### Why
481+
482+
`nvarchar(max)` columns are inefficient and unnecessary when the lengths of all possible values are known.
483+
484+
#### Mitigations
485+
486+
The column size can be made explicitly unbounded:
487+
488+
```csharp
489+
modelBuilder.Entity<Foo>()
490+
.Property<string>("Discriminator")
491+
.HasMaxLength(-1);
492+
```
493+
494+
<a name="casekeys"></a>
495+
496+
### SQL Server key values are compared case-insensitively
497+
498+
[Tracking Issue #27526](https://github.com/dotnet/efcore/issues/27526)
499+
500+
#### Old behavior
501+
502+
Previously, when tracking entities with string keys with the SQL Server/Azure SQL database providers, the key values were compared using the default .NET case-sensitive ordinal comparer.
503+
504+
#### New behavior
505+
506+
Starting with EF Core 8.0, SQL Server/Azure SQL string key values are compared using the default .NET case-insensitive ordinal comparer.
507+
508+
#### Why
509+
510+
By default, SQL Server uses case-insensitive comparisons when comparing foreign key values for matches to principal key values. This means when EF uses case-sensitive comparisons it may not connect a foreign key to a principal key when it should.
511+
512+
#### Mitigations
513+
514+
Case-sensitive comparisons can be used by setting a custom `ValueComparer`. For example:
515+
516+
```csharp
517+
protected override void OnModelCreating(ModelBuilder modelBuilder)
518+
{
519+
var comparer = new ValueComparer<string>(
520+
(l, r) => string.Equals(l, r, StringComparison.Ordinal),
521+
v => v.GetHashCode(),
522+
v => v);
523+
524+
modelBuilder.Entity<Blog>()
525+
.Property(e => e.Id)
526+
.Metadata.SetValueComparer(comparer);
527+
528+
modelBuilder.Entity<Post>(
529+
b =>
530+
{
531+
b.Property(e => e.Id).Metadata.SetValueComparer(comparer);
532+
b.Property(e => e.BlogId).Metadata.SetValueComparer(comparer);
533+
});
534+
}
535+
```

0 commit comments

Comments
 (0)