|
1 | 1 | --- |
2 | 2 | title: What's New in EF Core 10 |
3 | 3 | description: Overview of new features in EF Core 10 |
4 | | -author: maumar |
5 | | -ms.date: 01/05/2025 |
| 4 | +author: roji |
| 5 | +ms.date: 10/02/2025 |
6 | 6 | uid: core/what-is-new/ef-core-10.0/whatsnew |
7 | 7 | --- |
8 | 8 |
|
9 | 9 | # What's New in EF Core 10 |
10 | 10 |
|
11 | 11 | EF Core 10 (EF10) is the next release after EF Core 9 and is scheduled for release in November 2025. |
12 | 12 |
|
13 | | -EF10 is available as a preview. See [.NET 10 release notes](https://github.com/dotnet/core/tree/main/release-notes/10.0) to get information about the latest preview. This article will be updated as new preview releases are made available. |
| 13 | +EF10 is available as a preview. [See the .NET 10 release notes](https://github.com/dotnet/core/tree/main/release-notes/10.0) to get information about the latest .NET preview. |
14 | 14 |
|
15 | 15 | > [!TIP] |
16 | 16 | > You can run and debug into the samples by [downloading the sample code from GitHub](https://github.com/dotnet/EntityFramework.Docs). Each section below links to the source code specific to that section. |
17 | 17 |
|
18 | 18 | EF10 requires the .NET 10 SDK to build and requires the .NET 10 runtime to run. EF10 will not run on earlier .NET versions, and will not run on .NET Framework. |
19 | 19 |
|
| 20 | +The below release notes list the major improvements in the release; [the full list of issues for the release can be found here](https://github.com/dotnet/efcore/issues?q=is%3Aissue%20milestone%3A10.0.0). |
| 21 | + |
20 | 22 | <a name="sql-server"></a> |
21 | 23 |
|
22 | 24 | ## Azure SQL and SQL Server |
@@ -122,9 +124,6 @@ WHERE JSON_VALUE([b].[Details], '$.Viewers' RETURNING int) > 3 |
122 | 124 |
|
123 | 125 | Note that if your EF application already uses JSON via `nvarchar` columns, these columns will be automatically changed to `json` with the first migration. You can opt out of this by manually setting the column type to `nvarchar(max)`, or configuring a compatibility level lower than 170. |
124 | 126 |
|
125 | | -> [!NOTE] |
126 | | -> For 10.0.0 rc1, support for the new JSON data type has been temporarily disabled for Azure SQL Database, due to lacking support. These issues are expected to be resolved by the time EF 10.0 is released, and the JSON data type will become the default until then. |
127 | | -
|
128 | 127 | <a name="default-constraint-names"></a> |
129 | 128 |
|
130 | 129 | ### Custom default constraint names |
@@ -230,6 +229,12 @@ In previous versions of EF Core, evolving the model when using Azure Cosmos DB w |
230 | 229 |
|
231 | 230 | In EF 10 we improved this experience - EF will now materialize a default value for a required property, if no data is present for it in the document, rather than throw. |
232 | 231 |
|
| 232 | +<a name="other-cosmos-improvements"></a> |
| 233 | + |
| 234 | +## Other Cosmos improvements |
| 235 | + |
| 236 | +- Use ExecutionStrategy for query execution (for retrying) ([#35692](https://github.com/dotnet/efcore/issues/35692)). |
| 237 | + |
233 | 238 | <a name="complex-types"></a> |
234 | 239 |
|
235 | 240 | ## Complex types |
@@ -522,7 +527,7 @@ ORDER BY [b0].[Name], [b0].[Id] |
522 | 527 | ## ExecuteUpdate support for relational JSON columns |
523 | 528 |
|
524 | 529 | > [!NOTE] |
525 | | -> ExecuteUpdate support for JSON requires mapping your types as complex types, and does not work when you types are mapped as owned entities. |
| 530 | +> ExecuteUpdate support for JSON requires mapping your types as complex types ([see above](#json)), and does not work when your types are mapped as owned entities. |
526 | 531 |
|
527 | 532 | Although EF has support JSON columns for some time and allows updating them via `SaveChanges`, `ExecuteUpdate` lacked support for them. EF10 now allows referencing JSON columns and properties within them in `ExecuteUpdate`, allowing efficient bulk updating of document-modeled data within relational databases. |
528 | 533 |
|
@@ -630,10 +635,64 @@ Thanks to [@aradalvand](https://github.com/aradalvand) for proposing and pushing |
630 | 635 |
|
631 | 636 | <a name="other-improvements"></a> |
632 | 637 |
|
| 638 | +## Security-related improvements |
| 639 | + |
| 640 | +### Redact inlined constants from logging by default |
| 641 | + |
| 642 | +When logging executed SQL, EF does not log parameter values by default, since these may contain sensitive or personally-identifiable information (PII); <xref:Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.EnableSensitiveDataLogging> can be used to enable logging parameter values in diagnostic or debugging scenarios ([see documentation](xref:core/logging-events-diagnostics/extensions-logging#sensitive-data)). |
| 643 | + |
| 644 | +However, EF sometimes inlines parameters into the SQL statement rather than sending them separately; in those scenarios, the potentially sensitive values were logged. EF10 no longer does this, redacting such inlined parameters by default and replacing them with a question mark character (`?`). For example, let's say we have a function that accepts a list of roles, and returns the list of users which have one of those roles: |
| 645 | + |
| 646 | +```c# |
| 647 | +Task<List<User>> GetUsersByRoles(BlogContext context, string[] roles) |
| 648 | + => context.Users.Where(b => roles.Contains(b.Role)).ToListAsync(); |
| 649 | +``` |
| 650 | + |
| 651 | +Although the roles here are parameterized (may differ across invocations), we know that the actual sets of roles queried will be quite limited. We can therefore tell EF to *inline* the roles, so that the database's planner can plan execution separately for this query with its specific set of roles: |
| 652 | + |
| 653 | +```c# |
| 654 | +Task<List<User>> GetUsersByRoles(BlogContext context, string[] roles) |
| 655 | + => context.Users.Where(b => EF.Constant(roles).Contains(b.Role)).ToListAsync(); |
| 656 | +``` |
| 657 | + |
| 658 | +On previous versions of EF, this produced the following SQL: |
| 659 | + |
| 660 | +```sql |
| 661 | +SELECT [u].[Id], [u].[Role] |
| 662 | +FROM [Users] AS [u] |
| 663 | +WHERE [u].[Role] IN (N'Administrator', N'Manager') |
| 664 | +``` |
| 665 | + |
| 666 | +EF10 sends the same SQL to the database, but logs the following SQL, where the roles have been redacted: |
| 667 | + |
| 668 | +```sql |
| 669 | +SELECT [b].[Id], [b].[Role] |
| 670 | +FROM [Blogs] AS [b] |
| 671 | +WHERE [b].[Role] IN (?, ?) |
| 672 | +``` |
| 673 | + |
| 674 | +If the roles represent sensitive information, this prevents that information from leaking into the application logs. As with regular parameters, full logging can be reenabled via <xref:Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.EnableSensitiveDataLogging>. |
| 675 | + |
| 676 | +### Warn for string concatenation with raw SQL APIs |
| 677 | + |
| 678 | +SQL injection is one of the most serious security vulnerabilities in database applications; if unsanitized external input is inserted into SQL queries, a malicious user may be able to perform SQL injection, executing arbitrary SQL on your database. For more information about EF's SQL querying APIs and SQL injection, [see the documentation](xref:core/querying/sql-queries#passing-parameters). |
| 679 | + |
| 680 | +While EF users rarely deal with SQL directly, EF does provide SQL-based APIs for the cases where they're needed. Most of these APIs are safe in the face of SQL injection; for example <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql*> accepts a .NET `FormattableString`, and any parameter will automatically be send as a separate SQL parameter, preventing SQL injection. However, in some scenarios it's necessary to build up a dynamic SQL query by piecing together multiple fragments; <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw*> is designed specifically for this, and requires the user to ensure that all fragments are trusted or properly sanitized. |
| 681 | + |
| 682 | +Starting with EF10, EF has an analyzer which warns if concatenation is performed within a "raw" SQL method invocation: |
| 683 | + |
| 684 | +```c# |
| 685 | +var users = context.Users.FromSqlRaw("SELECT * FROM Users WHERE [" + fieldName + "] IS NULL"); |
| 686 | +``` |
| 687 | + |
| 688 | +If `fieldName` is trusted or has been properly sanitized, the warning can be safely suppressed. |
| 689 | + |
633 | 690 | ## Other improvements |
634 | 691 |
|
| 692 | +- Stop spanning all migrations with a single transaction ([#35096](https://github.com/dotnet/efcore/issues/35096)). This reverts a change done in EF9 which caused issues in various migration scenarios. |
635 | 693 | - Make SQL Server scaffolding compatible with Azure Data Explorer ([#34832](https://github.com/dotnet/efcore/pull/34832), contributed by [@barnuri](https://github.com/barnuri)). |
636 | 694 | - Associate the DatabaseRoot with the scoped options instance and not the singleton options ([#34477](https://github.com/dotnet/efcore/pull/34477), contributed by [@koenigst](https://github.com/koenigst)). |
637 | | -- Redact inlined constants from log when sensitive logging is off ([#35724](https://github.com/dotnet/efcore/pull/35724)). |
638 | 695 | - Improve LoadExtension to work correctly with dotnet run and lib* named libs ([#35617](https://github.com/dotnet/efcore/pull/35617), contributed by [@krwq](https://github.com/krwq)). |
639 | 696 | - Changes to AsyncLocal usage for better lazy loading performance ([#35835](https://github.com/dotnet/efcore/pull/35835), contributed by [@henriquewr](https://github.com/henriquewr)). |
| 697 | + |
| 698 | +[The full list of issues for the release can be found here](https://github.com/dotnet/efcore/issues?q=is%3Aissue%20milestone%3A10.0.0). |
0 commit comments