-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
Bug description
When upgrading from EF Core 9 to EF Core 10 with UseCompatibilityLevel(170), the migration generator
does not produce an AlterColumn operation to convert existing OwnsOne/OwnsMany columns configured
with ToJson() from nvarchar(max) to native json type.
Important clarifications:
- New projects work correctly: EF Core 10 generates
jsoncolumn type forToJson()columns in new
migrations - Primitive collections upgrade correctly: Existing
List<string>etc. columns ARE migrated from
nvarchar(max)tojson - ToJson() upgrade fails: Existing
ToJson()columns created by EF Core 9 are NOT migrated, causing
runtime failures
This causes runtime failures because EF Core 10 generates SQL that requires native json columns:
- INSERT fails:
Implicit conversion from data type json to nvarchar(max) is not allowed - SELECT fails:
Incorrect syntax near 'RETURNING'(EF Core generatesJSON_VALUE(...RETURNING type)which only works with nativejsoncolumns)
Expected behavior
When generating a migration after upgrading to EF Core 10 with UseCompatibilityLevel(170), an
AlterColumn should be generated to convert existing ToJson() columns from nvarchar(max) to json,
consistent with how primitive collections are handled.
Actual behavior
The generated migration is empty for ToJson() columns. The column remains nvarchar(max) while EF Core
10 generates SQL requiring native json type.
Workarounds
- Lower compatibility level to 160:
o.UseCompatibilityLevel(160)- disablesRETURNINGclause but
loses native JSON benefits - Manual migration: Add
AlterColumnstatements for eachToJson()column:migrationBuilder.AlterColumn<string>( name: "Details", table: "Blogs", type: "json", nullable: true, oldClrType: typeof(string), oldType: "nvarchar(max)", oldNullable: true);
- Explicit column type: Add .HasColumnType("json") to all ToJson() configurations, then regenerate
migration:
modelBuilder.Entity().OwnsOne(b => b.Details, b => b.ToJson().HasColumnType("json"));
Your code
### Model
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(connectionString, o => o.UseCompatibilityLevel(170));
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().OwnsOne(b => b.Details, b => b.ToJson());
}
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; } = "";
public BlogDetails? Details { get; set; }
}
public class BlogDetails
{
public string Author { get; set; } = "";
public int Viewers { get; set; }
}
Repro steps
1. Create project with EF Core 9.0.11 and generate initial migration:
dotnet ef migrations add Initial
1. This correctly creates Details as nvarchar(max):
Details = table.Column<string>(type: "nvarchar(max)", nullable: true)
2. Upgrade to EF Core 10.0.0 and add UseCompatibilityLevel(170) to DbContext
3. Generate upgrade migration:
dotnet ef migrations add UpgradeToEF10
4. Observe: Migration is empty - no AlterColumn generated
5. Apply migrations and run query:
var blogs = await context.Blogs.Where(b => b.Details!.Viewers > 50).ToListAsync();
6. Observe: Query fails with Incorrect syntax near 'RETURNING'Stack traces
### INSERT error (when EF Core tries to insert data)
Microsoft.Data.SqlClient.SqlException (0x80131904): Implicit conversion from data type json to
nvarchar(max) is not allowed. Use the CONVERT function to run this query.
at Microsoft.Data.SqlClient.SqlCommand.<>c.b__195_0(Task`1 result)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParamet
erObject parameterObject, CancellationToken cancellationToken)
at
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection
connection, CancellationToken cancellationToken)
### SELECT error (when querying with JSON property filter)
Microsoft.Data.SqlClient.SqlException: Incorrect syntax near 'RETURNING'.
Generated SQL that fails:
SELECT ... FROM [Blogs] AS [b] WHERE JSON_VALUE([b].[Details], '$.Viewers' RETURNING int) > 50
The RETURNING clause only works with native json columns, not nvarchar(max).
EF Core version
10.0.0
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 10.0
Operating system
macOS Tahoe 26.1
IDE
No response