Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
EF Core 10 (EF10) is the next release after EF Core 9 and is scheduled for release in November 2025.
EF10 is available as a preview. See .NET 10 release notes to get information about the latest preview. This article will be updated as new preview releases are made available.
Tip
You can run and debug into the samples by downloading the sample code from GitHub. Each section below links to the source code specific to that section.
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.
Azure Cosmos DB for NoSQL
Full-text search support
Azure Cosmos DB now offers support for full-text search. It enables efficient and effective text searches, as well as evaluating the relevance of documents to a given search query. It can be used in combination with vector search to improve the accuracy of responses in some AI scenarios. EF Core 10 is adding support for this feature allowing for modeling the database with full-text search enabled properties and using full-text search functions inside queries targeting Azure Cosmos DB.
Here is a basic EF model configuration enabling full-text search on one of the properties:
public class Blog
{
...
public string Contents { get; set; }
}
public class BloggingContext
{
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>(b =>
{
b.Property(x => x.Contents).EnableFullTextSearch();
b.HasIndex(x => x.Contents).IsFullTextIndex();
});
}
}
Once the model is configured, we can use full-text search operations in queries using methods provided in EF.Functions
:
var cosmosBlogs = await context.Blogs.Where(x => EF.Functions.FullTextContains(x.Contents, "cosmos")).ToListAsync();
The following full-text operations are currently supported: FullTextContains
, FullTextContainsAll
, FullTextContainsAny
, FullTextScore
.
For more information on Cosmos full-text search, see the docs.
Hybrid search
EF Core now supports RRF
(Reciprocal Rank Fusion) function, which combines vector similarity search and full-text search (i.e. hybrid search). Here is an example query using hybrid search:
float[] myVector = /* generate vector data from text, image, etc. */
var hybrid = await context.Blogs.OrderBy(x => EF.Functions.Rrf(
EF.Functions.FullTextScore(x.Contents, "database"),
EF.Functions.VectorDistance(x.Vector, myVector)))
.Take(10)
.ToListAsync();
For more information on Cosmos hybrid search, see the docs.
Vector similarity search exits preview
In EF9 we added experimental support for vector similarity search. In EF Core 10, vector similarity search support is no longer experimental. We have also made some improvements to the feature:
- EF Core can now generate containers with vector properties defined on owned reference entities. Containers with vector properties defined on owned collections still have to be created by other means. However, they can be used in queries.
- Model building APIs have been renamed. A vector property can now be configured using the
IsVectorProperty
method, and vector index can be configured using theIsVectorIndex
method.
For more information on Cosmos vector search, see the docs.
Improved experience when evolving the model
In previous versions of EF Core, evolving the model when using Azure Cosmos DB was quite painful. Specifically, when adding a new required property to the entity, EF would no longer be able to materialize that entity. The reason was that EF expected a value for the new property (since it was required), but the document created before the change didn't contain those values. The workaround was to mark the property as optional first, manually add default values for the property, and only then change it to required.
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.
LINQ and SQL translation
Support for the .NET 10 LeftJoin
and RightJoin
operators
LEFT JOIN
is a common and useful operation when working with EF Core. In previous versions, implementing LEFT JOIN
in LINQ was quite complicated, requiring SelectMany
, GroupJoin
and DefaultIfEmpty
operations in a particular configuration.
.NET 10 adds first-class LINQ support for LeftJoin
method, making those queries much simpler to write. EF Core recognizes the new method, so it can be used in EF LINQ queries instead of the old construct:
var query = context.Students
.LeftJoin(
context.Departments,
student => student.DepartmentID,
department => department.ID,
(student, department) => new
{
student.FirstName,
student.LastName,
Department = department.Name ?? "[NONE]"
});
Note
EF 10 also supports the analogous RightJoin
operator, which keeps all the data from the second collection and only the matching data from the first collection. EF 10 translates this to RIGHT JOIN
operation in the database.
See #12793 and #35367 for more details.
Other query improvements
- Translate DateOnly.ToDateTime(timeOnly) (#35194, contributed by @mseada94).
- Optimize multiple consecutive
LIMIT
s (#35384, contributed by @ranma42). - Optimize use of
Count
operation onICollection<T>
(#35381, contributed by @ChrisJollyAU). - Optimize
MIN
/MAX
overDISTINCT
(#34699, contributed by @ranma42). - Translate date/time functions using
DatePart.Microsecond
andDatePart.Nanosecond
arguments (#34861). - Simplify parameter names (e.g. from
@__city_0
tocity
) (#35200). - Translate
COALESCE
asISNULL
on SQL Server, for most cases (#34171, contributed by @ranma42). - Support some string functions taking
char
as arguments (#34999, contributed by @ChrisJollyAU). - Support
MAX
/MIN
/ORDER BY
usingdecimal
on SQLite (#35606, contributed by @ranma42).
ExecuteUpdateAsync now accepts a regular, non-expression lambda
The ExecuteUpdateAsync can be used to express arbitrary update operations in the database. In previous versions, the changes to be performed on the database rows were provided via an expression tree parameter; this made it quite difficult to build those changes dynamically. For example, let's assume we want to update a Blog's Views, but conditionally also its Name. Since the setters argument was an expression tree, code such as the following needed to be written:
// Base setters - update the Views only
Expression<Func<SetPropertyCalls<Blog>, SetPropertyCalls<Blog>>> setters =
s => s.SetProperty(b => b.Views, 8);
// Conditionally add SetProperty(b => b.Name, "foo") to setters, based on the value of nameChanged
if (nameChanged)
{
var blogParameter = Expression.Parameter(typeof(Blog), "b");
setters = Expression.Lambda<Func<SetPropertyCalls<Blog>, SetPropertyCalls<Blog>>>(
Expression.Call(
instance: setters.Body,
methodName: nameof(SetPropertyCalls<Blog>.SetProperty),
typeArguments: [typeof(string)],
arguments:
[
Expression.Lambda<Func<Blog, string>>(Expression.Property(blogParameter, nameof(Blog.Name)), blogParameter),
Expression.Constant("foo")
]),
setters.Parameters);
}
await context.Blogs.ExecuteUpdateAsync(setters);
Manually creating expression trees is complicated and error-prone, and made this common scenario much more difficult than it should have been. Starting with EF 10, you can now write the following instead:
await context.Blogs.ExecuteUpdateAsync(s =>
{
s.SetProperty(b => b.Views, 8);
if (nameChanged)
{
s.SetProperty(b => b.Name, "foo");
}
});
Thanks to @aradalvand for proposing and pushing for this change (in #32018).
Other improvements
- Make SQL Server scaffolding compatible with Azure Data Explorer (#34832, contributed by @barnuri).
- Associate the DatabaseRoot with the scoped options instance and not the singleton options (#34477, contributed by @koenigst).
- Redact inlined constants from log when sensitive logging is off (#35724).
- Improve LoadExtension to work correctly with dotnet run and lib* named libs (#35617, contributed by @krwq).
- Change AsyncLocal to ThreadId for better Lazy loader performance (#35835, contributed by @henriquewr).