From e97d88221a97c902d26887fef4ac176940b3c11a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Jul 2026 01:54:38 +0000 Subject: [PATCH 1/5] Initial plan From b2b5d64bdc152dd7a2dfe3c2dc34c5a5fac09ec5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Jul 2026 01:59:41 +0000 Subject: [PATCH 2/5] Document breaking change: NoTrackingWithIdentityResolution prohibited for JSON collections (EF Core 9) --- .../ef-core-9.0/breaking-changes.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) 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 b0e76a7f4c..04aa95c059 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 @@ -35,6 +35,7 @@ EF Core 9 targets .NET 8. This means that existing applications that target .NET | [Shared framework dependencies were updated to 9.0.x](#shared-framework-dependencies) | Low | | [EF tools no longer support .NET Framework projects](#ef-tools-no-netfx) | Low | | [`EF.Constant()` and `EF.Parameter()` no longer work inside compiled queries](#ef-constant-compiled) | Low | +| [Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections](#no-tracking-with-identity-resolution-json) | Low | ## High-impact changes @@ -389,6 +390,66 @@ The internal implementation of Either remove the or call from the compiled query, or stop using a compiled query for that particular query. Note that removing `EF.Constant()` causes the value to be sent as a SQL parameter rather than inlined as a constant, which may affect query plan performance. + + +### Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections + +[Tracking Issue #33073](https://github.com/dotnet/efcore/issues/33073) + +#### Old behavior + +Previously, using (or setting ) with queries that include JSON-mapped entity collections could silently produce incorrect results or data corruption, depending on the order in which entities were processed during materialization. Additionally, such queries could throw an unhelpful `"Invalid token type: 'StartObject'"` exception in some scenarios. + +#### New behavior + +Starting with EF Core 9.0, EF Core restricts the use of for certain JSON collection query patterns, to prevent silent data corruption: + +- If entity instances in a JSON collection would be materialized in an order that could cause data corruption, EF Core throws an exception instructing the user to use a different tracking behavior. +- Using LINQ queryable operators (such as `OrderBy`, `Where`, `Skip`, `Take`, etc.) directly on JSON collection navigations in a query with `AsNoTrackingWithIdentityResolution()` is now prohibited. For example, the following query would throw an exception: + +```csharp +var blogs = await context.Blogs + .AsNoTrackingWithIdentityResolution() + .Select(b => new + { + Blog = b, + TopPosts = b.JsonPosts.OrderBy(p => p.Rating).Take(3).ToList() + }) + .ToListAsync(); +``` + +#### Why + +The combination of and JSON collections could silently produce incorrect materialized objects due to how JSON is streamed from the database: nested includes in JSON are part of the parent's materialization rather than being materialized separately. The identity resolution change tracker relies on key values to deduplicate entity instances, but when queryable operators are applied to JSON collections, EF Core cannot reliably propagate those key values to the materializer, resulting in entities with null keys and potential data corruption. + +#### Mitigations + +Use a regular tracking query if identity resolution is required: + +```csharp +var blogs = await context.Blogs + .AsTracking() + .Select(b => new + { + Blog = b, + TopPosts = b.JsonPosts.OrderBy(p => p.Rating).Take(3).ToList() + }) + .ToListAsync(); +``` + +If you do not need identity resolution, use instead: + +```csharp +var blogs = await context.Blogs + .AsNoTracking() + .Select(b => new + { + Blog = b, + TopPosts = b.JsonPosts.OrderBy(p => p.Rating).Take(3).ToList() + }) + .ToListAsync(); +``` + ## Azure Cosmos DB breaking changes Extensive work has gone into making the Azure Cosmos DB provider better in 9.0. The changes include a number of high-impact breaking changes; if you are upgrading an existing application, please read the following carefully. From 67a26d236802ac90c856bf1cefaf22566cc31b54 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Thu, 2 Jul 2026 19:38:53 -0700 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../core/what-is-new/ef-core-9.0/breaking-changes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 04aa95c059..52ae1d07bd 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 @@ -405,7 +405,7 @@ Previously, using for certain JSON collection query patterns, to prevent silent data corruption: - If entity instances in a JSON collection would be materialized in an order that could cause data corruption, EF Core throws an exception instructing the user to use a different tracking behavior. -- Using LINQ queryable operators (such as `OrderBy`, `Where`, `Skip`, `Take`, etc.) directly on JSON collection navigations in a query with `AsNoTrackingWithIdentityResolution()` is now prohibited. For example, the following query would throw an exception: +- Using LINQ operators (such as `OrderBy`, `Where`, `Skip`, `Take`, etc.) directly on JSON collection navigations in a query with `AsNoTrackingWithIdentityResolution()` is now prohibited. For example, the following query would throw an exception: ```csharp var blogs = await context.Blogs @@ -420,7 +420,7 @@ var blogs = await context.Blogs #### Why -The combination of and JSON collections could silently produce incorrect materialized objects due to how JSON is streamed from the database: nested includes in JSON are part of the parent's materialization rather than being materialized separately. The identity resolution change tracker relies on key values to deduplicate entity instances, but when queryable operators are applied to JSON collections, EF Core cannot reliably propagate those key values to the materializer, resulting in entities with null keys and potential data corruption. +The combination of and JSON collections could silently produce incorrect materialized objects due to how JSON is streamed from the database: nested includes in JSON are part of the parent's materialization rather than being materialized separately. The stand-alone change tracker used for identity resolution relies on key values to deduplicate entity instances, but when LINQ operators are applied to JSON collections, EF Core cannot reliably propagate those key values to the materializer, resulting in entities with null keys and potential data corruption. #### Mitigations From cb1569faff02ca30bbd13015a140460bbff6a541 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Jul 2026 02:40:26 +0000 Subject: [PATCH 4/5] docs: rename no-tracking JSON anchor --- .../core/what-is-new/ef-core-9.0/breaking-changes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 52ae1d07bd..4c3d134bc4 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 @@ -35,7 +35,7 @@ EF Core 9 targets .NET 8. This means that existing applications that target .NET | [Shared framework dependencies were updated to 9.0.x](#shared-framework-dependencies) | Low | | [EF tools no longer support .NET Framework projects](#ef-tools-no-netfx) | Low | | [`EF.Constant()` and `EF.Parameter()` no longer work inside compiled queries](#ef-constant-compiled) | Low | -| [Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections](#no-tracking-with-identity-resolution-json) | Low | +| [Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections](#no-tracking-json) | Low | ## High-impact changes @@ -390,7 +390,7 @@ The internal implementation of Either remove the or call from the compiled query, or stop using a compiled query for that particular query. Note that removing `EF.Constant()` causes the value to be sent as a SQL parameter rather than inlined as a constant, which may affect query plan performance. - + ### Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections From 0aac89261a93514371c6948711ce91e771196c18 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Thu, 2 Jul 2026 21:47:52 -0700 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../core/what-is-new/ef-core-9.0/breaking-changes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 4c3d134bc4..4733077c1a 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 @@ -35,7 +35,7 @@ EF Core 9 targets .NET 8. This means that existing applications that target .NET | [Shared framework dependencies were updated to 9.0.x](#shared-framework-dependencies) | Low | | [EF tools no longer support .NET Framework projects](#ef-tools-no-netfx) | Low | | [`EF.Constant()` and `EF.Parameter()` no longer work inside compiled queries](#ef-constant-compiled) | Low | -| [Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections](#no-tracking-json) | Low | +| [Some `NoTrackingWithIdentityResolution` queries are now prohibited for JSON collections](#no-tracking-json) | Low | ## High-impact changes @@ -398,7 +398,7 @@ Either remove the or (or setting ) with queries that include JSON-mapped entity collections could silently produce incorrect results or data corruption, depending on the order in which entities were processed during materialization. Additionally, such queries could throw an unhelpful `"Invalid token type: 'StartObject'"` exception in some scenarios. +Previously, using (or setting ) with queries that include JSON-mapped entity collections could silently produce incorrect results or data corruption, depending on the order in which entities were processed during materialization. Additionally, such queries could throw an unhelpful `Invalid token type: 'StartObject'` exception in some scenarios. #### New behavior