.NET 11 Preview 4 includes new EF Core features and tooling improvements:
- Approximate vector search for SQL Server 2025
- JSON mapping is fully integrated into the relational model
- Temporal period properties can map to CLR properties
- More SQL Server
DateTimeOffsettranslations dotnet efreads defaults fromdotnet-ef.json- Clearer warning when a migration snapshot is from an older EF Core version
- Breaking changes
- Bug fixes
- Community contributors
EF Core updates in .NET 11:
EF Core now translates approximate nearest-neighbor (ANN) vector queries against
SQL Server 2025 (dotnet/efcore #38075).
Calling VectorSearch() returns rows ordered by vector distance, and adding
WithApproximate() instructs SQL Server to use a vector index — translating to
the WITH APPROXIMATE clause introduced in SQL Server 2025. Without
WithApproximate(), EF Core emits an exact (brute-force) search, which is
useful for verifying recall on small data sets.
var query = await context.Blogs
.VectorSearch(b => b.Embedding, queryVector)
.WithApproximate()
.Take(10)
.ToListAsync();This builds on the SQL Server 2025 vector index configuration that landed in earlier .NET 11 previews; together they give EF Core a full ANN search story against SQL Server's native vector type.
JSON columns are now first-class citizens in the relational model
(dotnet/efcore #38038). The path
that EF Core uses to update a slice of a JSON document is now represented as a
structured JsonPath/JsonPathSegment instead of a JSON-path string built up
during command generation. This unblocks better diagnostics, more reliable
partial-update SQL, and fixes long-standing issues where the generated path did
not round-trip correctly through migrations and compiled models
(closes dotnet/efcore#36646, dotnet/efcore#32185).
For most applications this is internal plumbing — your OwnsOne / OwnsMany
JSON mappings keep working unchanged. Provider authors and anyone reading
generated migration snapshots will see the new structured path representation.
SQL Server temporal tables have always required PeriodStart and PeriodEnd
to be shadow properties. Preview 4 lifts that restriction so you can expose the
period columns as regular CLR properties on your entity and read them like any
other column (dotnet/efcore #38110,
closes dotnet/efcore#26463). The temporal builders also gain strongly-typed
HasPeriodStart / HasPeriodEnd overloads that accept a lambda.
public class Order
{
public int Id { get; set; }
public string Status { get; set; } = "";
public DateTime PeriodStart { get; set; }
public DateTime PeriodEnd { get; set; }
}
modelBuilder.Entity<Order>().ToTable(tb => tb.IsTemporal(ttb =>
{
ttb.HasPeriodStart(o => o.PeriodStart);
ttb.HasPeriodEnd(o => o.PeriodEnd);
}));EF Core continues to manage the values — the properties are still configured
with ValueGenerated.OnAddOrUpdate and BeforeSaveBehavior.Ignore, so writes
still flow through SQL Server's SYSTEM_TIME machinery.
Several common DateTimeOffset operations now translate to SQL on SQL Server
(dotnet/efcore #38076, closes
dotnet/efcore#26781, dotnet/efcore#34756, dotnet/efcore#38074). Queries
that previously failed with a "could not be translated" exception — or silently
fell back to client evaluation in older versions — now run on the database.
var recent = await context.Events
.Where(e => e.OccurredAt.Date == today)
.Where(e => e.OccurredAt.Year == 2026)
.OrderBy(e => e.OccurredAt.TimeOfDay)
.ToListAsync();dotnet ef can now load default values for common options from a
.config/dotnet-ef.json file (dotnet/efcore #37966,
closes dotnet/efcore#35231). Discovery walks up from the working directory,
similar to how .editorconfig or global.json are resolved, so the same
defaults apply whether you run dotnet ef migrations add from the solution
root or from a sub-folder. Command-line arguments still take precedence.
# No more --project / --startup-project / --context on every invocation
dotnet ef migrations add InitialCreateSupported keys include project, startupProject, framework,
configuration, context, runtime, verbose, noColor, and
prefixOutput. Thank you @IMZihad21 for this
contribution!
When Migrate() detects pending model changes, EF Core can now distinguish
between "you really did change your model" and "your snapshot was generated by
an older major version of EF Core" (dotnet/efcore #38065).
In the second case it raises a new RelationalEventId.OldMigrationVersionWarning
instead of PendingModelChangesWarning, pointing you at the likely root cause —
regenerating the snapshot rather than adding a redundant migration. The warning
only fires when the snapshot's major version is older than the running EF Core
major version and the detected changes are deterministic.
- SQL Server full-text and vector index builder API renames. Following
API review, several recently introduced builder methods were renamed and a
set of
IndexBuilderextension methods was removed (dotnet/efcore #38027). OnSqlServerFullTextIndexBuilder:HasKeyIndex→UseKeyIndex,OnCatalog→UseCatalog,WithChangeTracking→HasChangeTracking,HasLanguage→UseLanguage. OnSqlServerVectorIndexBuilder:UseMetric→HasMetric,UseType→HasType. TheHasFullTextKeyIndex/HasFullTextCatalog/HasFullTextChangeTracking/HasFullTextLanguageextension methods onIndexBuilderwere removed; use the dedicated full-text index builder instead.FullTextSearchResultmoved to theMicrosoft.EntityFrameworkCore.Querynamespace, and theContainsTable/FreeTextTableoverloads were collapsed by makingcolumnSelectoroptional and reordering parameters. - SQLite migrations no longer use
PRAGMA defer_foreign_keys. A previous change to usePRAGMA defer_foreign_keysinstead ofPRAGMA foreign_keysduring migrations has been reverted because it broke applications that rely on foreign-key enforcement during a migration script (dotnet/efcore #38120, revertsdotnet/efcore#35873, fixesdotnet/efcore#37598).
-
Inheritance (TPC)
- Fixed Table-Per-Concrete queries returning incorrect entity types when
derived types are generic (e.g.
Entity<int>andEntity<string>shared a discriminator) (dotnet/efcore #38022). - Fixed
SaveChangesinsert ordering for TPC hierarchies whose principal is an abstract base type, which previously caused FK constraint violations (dotnet/efcore #38070, fixesdotnet/efcore#35978). Thank you @andrewraper-Sage for this contribution!
- Fixed Table-Per-Concrete queries returning incorrect entity types when
derived types are generic (e.g.
-
ExecuteUpdate- Fixed
SetPropertywith a discard lambda assigning a constant to a nullable value-type property (e.g._ => 1on anint?), which threwInvalidOperationException: No coercion operator is defined(dotnet/efcore #38007).
- Fixed
-
JSON columns
- Value converters that translate
nullare now invoked fornullvalues on JSON-mapped properties (dotnet/efcore #37984). Thank you @JoasE for this contribution! JsonReaderDatanow reuses the underlying buffer of aMemoryStreaminstead of copying it, removing duplicate buffering on JSON reads (dotnet/efcore #38051). Thank you @JoasE for this contribution!
- Value converters that translate
-
Change tracking and complex properties
- Fixed
DbContext.Update()falsely markingAfterSaveBehavior.Throwproperties (such as discriminators on nullable complex types) as modified duringDetectChanges(dotnet/efcore #38115, fixesdotnet/efcore#38105).
- Fixed
-
SQL Server temporal tables
- Migrations no longer fail with "history table has IDENTITY column
specification" when an identity column is added while versioning is
temporarily disabled (dotnet/efcore #38019,
fixes
dotnet/efcore#36025). - Full-text catalog operations are no longer emitted when creating the
__EFMigrationsHistorytable, which previously caused prematureCREATE FULLTEXT CATALOGstatements (dotnet/efcore #38050).
- Migrations no longer fail with "history table has IDENTITY column
specification" when an identity column is added while versioning is
temporarily disabled (dotnet/efcore #38019,
fixes
-
Servicing fixes flowed forward from EF Core 10
Bug fixes shipped in EF Core 10.x servicing also flow into the .NET 11 Preview 4 builds. Notable items include:
- Comparing a split entity (
SplitToTable) tonullin a LINQ query no longer throwsSequence contains more than one element(dotnet/efcore #37987, fixesdotnet/efcore#35293). IEnumerable<TEnum>parameters with mismatched-but-compatible enum types no longer throwInvalidCastException(dotnet/efcore #38021, fixesdotnet/efcore#38008).- Primitive collection parameters containing
nullvalues no longer throwInvalidCastExceptionduring execution (dotnet/efcore #38066, fixesdotnet/efcore#37537). - Complex properties are no longer treated as nullable after upgrading from
EF Core 9 to 10, eliminating spurious
PendingModelChangesWarningand emptyAlterColumnmigrations (dotnet/efcore #38045, fixesdotnet/efcore#38043). - Discriminator changes on nullable complex properties are now persisted
when transitioning from
nullto non-null(dotnet/efcore #38134, fixesdotnet/efcore#38119). - Query filters that capture primary-constructor parameters no longer
produce invalid SQL parameter names containing angle brackets
(dotnet/efcore #38136, fixes
dotnet/efcore#38132). - Optional complex properties whose values are all defaults now correctly
persist as
null(dotnet/efcore #37952, port ofdotnet/efcore#37944). Thank you @Pmyl for this contribution!
- Comparing a split entity (
Thank you to the community contributors who made EF Core better in this preview:
- @andrewraper-Sage: Fixed insert ordering for TPC hierarchies with an abstract base type (dotnet/efcore #38070).
- @IMZihad21:
Added
dotnet-ef.jsonconfig defaults fordotnet ef(dotnet/efcore #37966). - @JoasE:
Ran value converters that translate
nullfor JSON columns (dotnet/efcore #37984) and optimizedJsonReaderDataforMemoryStreamsources (dotnet/efcore #38051). Also modernized the Cosmos JSON serialization pipeline (dotnet/efcore #38024). - @Pmyl: Fixed persisting null optional complex properties with default values (servicing port, dotnet/efcore #37952).