From d0284cba7f45d542f3460f8928bc4a819992ec68 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 20:33:18 +0000
Subject: [PATCH 1/3] Initial plan
From a8d39ffb7a0bc5ab4948681068420184825c0325 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 20:36:21 +0000
Subject: [PATCH 2/3] Document better SQL for to-one joins
Document https://github.com/dotnet/efcore/pull/37819
Co-authored-by: roji <1862641+roji@users.noreply.github.com>
---
.../core/what-is-new/ef-core-11.0/whatsnew.md | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
index a519703cec..29906e7e5f 100644
--- a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
+++ b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
@@ -128,6 +128,68 @@ WHERE JSON_PATH_EXISTS([b].[JsonData], N'$.OptionalInt') = 1
For the full `JSON_PATH_EXISTS` SQL Server documentation, see [`JSON_PATH_EXISTS`](/sql/t-sql/functions/json-path-exists-transact-sql).
+
+
+### Better SQL for to-one joins
+
+EF Core 11 generates better SQL when querying with to-one (reference) navigation includes in two ways.
+
+First, when using split queries (`AsSplitQuery()`), EF previously added unnecessary joins to reference navigations in the SQL generated for collection queries. For example, consider the following query:
+
+```csharp
+var blogs = context.Blogs
+ .Include(b => b.BlogType)
+ .Include(b => b.Posts)
+ .AsSplitQuery()
+ .ToList();
+```
+
+EF Core previously generated a split query for `Posts` that unnecessarily joined `BlogType`:
+
+```sql
+-- Before EF Core 11
+SELECT [p].[Id], [p].[BlogId], [p].[Title], [b].[Id], [b0].[Id]
+FROM [Blogs] AS [b]
+INNER JOIN [BlogType] AS [b0] ON [b].[BlogTypeId] = [b0].[Id]
+INNER JOIN [Post] AS [p] ON [b].[Id] = [p].[BlogId]
+ORDER BY [b].[Id], [b0].[Id]
+```
+
+In EF Core 11, the unneeded join is pruned:
+
+```sql
+-- EF Core 11
+SELECT [p].[Id], [p].[BlogId], [p].[Title], [b].[Id]
+FROM [Blogs] AS [b]
+INNER JOIN [Post] AS [p] ON [b].[Id] = [p].[BlogId]
+ORDER BY [b].[Id]
+```
+
+Second, EF no longer adds redundant keys from reference navigations to `ORDER BY` clauses. Because a reference navigation's key is functionally determined by the parent entity's key (via the foreign key), it does not need to appear separately. For example:
+
+```csharp
+var blogs = context.Blogs
+ .Include(b => b.Owner)
+ .Include(b => b.Posts)
+ .ToList();
+```
+
+EF Core previously included `[p].[PersonId]` in the `ORDER BY`, even though `[b].[BlogId]` already uniquely identifies the row:
+
+```sql
+-- Before EF Core 11
+ORDER BY [b].[BlogId], [p].[PersonId]
+```
+
+In EF Core 11, the redundant column is omitted:
+
+```sql
+-- EF Core 11
+ORDER BY [b].[BlogId]
+```
+
+Both optimizations can have a significant positive impact on query performance, especially when multiple reference navigations are included.
+
## Cosmos DB
From b06d632a14b8ec111be48b0ed951f00b68845807 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 9 Mar 2026 20:45:26 +0000
Subject: [PATCH 3/3] Move "Better SQL for to-one joins" to first position
under LINQ and SQL translation
Co-authored-by: roji <1862641+roji@users.noreply.github.com>
---
.../core/what-is-new/ef-core-11.0/whatsnew.md | 98 +++++++++----------
1 file changed, 49 insertions(+), 49 deletions(-)
diff --git a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
index 29906e7e5f..fc5ab2ed0c 100644
--- a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
+++ b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
@@ -79,55 +79,6 @@ For more information on inheritance mapping strategies, see [Inheritance](xref:c
## LINQ and SQL translation
-
-
-### MaxBy and MinBy
-
-EF Core now supports translating the LINQ `MaxByAsync` and `MinByAsync` methods (and their sync counterparts). These methods allow you to find the element with the maximum or minimum value for a given key selector, rather than just the maximum or minimum value itself.
-
-For example, to find the blog with the most posts:
-
-```csharp
-var blogWithMostPosts = await context.Blogs.MaxByAsync(b => b.Posts.Count());
-```
-
-This translates to the following SQL:
-
-```sql
-SELECT TOP(1) [b].[Id], [b].[Name]
-FROM [Blogs] AS [b]
-ORDER BY (
- SELECT COUNT(*)
- FROM [Posts] AS [p]
- WHERE [b].[Id] = [p].[BlogId]) DESC
-```
-
-Similarly, `MinByAsync` orders ascending and returns the element with the minimum value for the key selector.
-
-### EF.Functions.JsonPathExists()
-
-EF Core 11 introduces `EF.Functions.JsonPathExists()`, which checks whether a given JSON path exists in a JSON document. On SQL Server, this translates to the [`JSON_PATH_EXISTS`](/sql/t-sql/functions/json-path-exists-transact-sql) function (available since SQL Server 2022).
-
-The following query filters blogs to those whose JSON data contains an `OptionalInt` property:
-
-```csharp
-var blogs = await context.Blogs
- .Where(b => EF.Functions.JsonPathExists(b.JsonData, "$.OptionalInt"))
- .ToListAsync();
-```
-
-This generates the following SQL:
-
-```sql
-SELECT [b].[Id], [b].[Name], [b].[JsonData]
-FROM [Blogs] AS [b]
-WHERE JSON_PATH_EXISTS([b].[JsonData], N'$.OptionalInt') = 1
-```
-
-`EF.Functions.JsonPathExists()` accepts a JSON value and a JSON path to check for. It can be used with scalar string properties, complex types, and owned entity types mapped to JSON columns.
-
-For the full `JSON_PATH_EXISTS` SQL Server documentation, see [`JSON_PATH_EXISTS`](/sql/t-sql/functions/json-path-exists-transact-sql).
-
### Better SQL for to-one joins
@@ -190,6 +141,55 @@ ORDER BY [b].[BlogId]
Both optimizations can have a significant positive impact on query performance, especially when multiple reference navigations are included.
+
+
+### MaxBy and MinBy
+
+EF Core now supports translating the LINQ `MaxByAsync` and `MinByAsync` methods (and their sync counterparts). These methods allow you to find the element with the maximum or minimum value for a given key selector, rather than just the maximum or minimum value itself.
+
+For example, to find the blog with the most posts:
+
+```csharp
+var blogWithMostPosts = await context.Blogs.MaxByAsync(b => b.Posts.Count());
+```
+
+This translates to the following SQL:
+
+```sql
+SELECT TOP(1) [b].[Id], [b].[Name]
+FROM [Blogs] AS [b]
+ORDER BY (
+ SELECT COUNT(*)
+ FROM [Posts] AS [p]
+ WHERE [b].[Id] = [p].[BlogId]) DESC
+```
+
+Similarly, `MinByAsync` orders ascending and returns the element with the minimum value for the key selector.
+
+### EF.Functions.JsonPathExists()
+
+EF Core 11 introduces `EF.Functions.JsonPathExists()`, which checks whether a given JSON path exists in a JSON document. On SQL Server, this translates to the [`JSON_PATH_EXISTS`](/sql/t-sql/functions/json-path-exists-transact-sql) function (available since SQL Server 2022).
+
+The following query filters blogs to those whose JSON data contains an `OptionalInt` property:
+
+```csharp
+var blogs = await context.Blogs
+ .Where(b => EF.Functions.JsonPathExists(b.JsonData, "$.OptionalInt"))
+ .ToListAsync();
+```
+
+This generates the following SQL:
+
+```sql
+SELECT [b].[Id], [b].[Name], [b].[JsonData]
+FROM [Blogs] AS [b]
+WHERE JSON_PATH_EXISTS([b].[JsonData], N'$.OptionalInt') = 1
+```
+
+`EF.Functions.JsonPathExists()` accepts a JSON value and a JSON path to check for. It can be used with scalar string properties, complex types, and owned entity types mapped to JSON columns.
+
+For the full `JSON_PATH_EXISTS` SQL Server documentation, see [`JSON_PATH_EXISTS`](/sql/t-sql/functions/json-path-exists-transact-sql).
+
## Cosmos DB