Bug description
In ef core 10 there is a regression preventing us from updating. When using any entity which has an OwnsMany or OwnsOne which is selected via a DbFunction an object reference error occurs while compiling the query
Your code
using Microsoft.EntityFrameworkCore;
namespace EFCore10ReproductionTest;
// ============================================================
// Minimal self-contained reproduction of EF Core 10 bug:
// NullReferenceException in AddJsonNavigationBindings
// when combining [DbFunction] with OwnsOne/OwnsMany().ToJson()
//
// Bug report: https://github.com/dotnet/efcore/issues/37842
// ============================================================
// --- Minimal entity with an owned JSON type ---
public class MinimalEntity
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public MinimalOwnedType OwnedData { get; set; } = new();
}
public class MinimalOwnedType
{
public string? Value { get; set; }
}
// --- Minimal DbContext ---
public class MinimalDbContext : DbContext
{
public DbSet<MinimalEntity> Entities { get; set; } = null!;
// [DbFunction] returning IQueryable<MinimalEntity> - this is the trigger
[DbFunction(Name = "GetEntities", Schema = "dbo")]
public IQueryable<MinimalEntity> GetEntities() => FromExpression(() => GetEntities());
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
// Must use SQL Server provider - the InMemory provider does NOT trigger the bug
builder.UseSqlServer("Server=fake;Database=fake;Trusted_Connection=yes;Connect Timeout=1");
builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MinimalEntity>(b =>
{
b.HasKey(x => x.Id);
b.ToTable("MinimalEntities");
// OwnsOne with ToJson() - this is the second ingredient of the bug
b.OwnsOne(x => x.OwnedData, o => o.ToJson("owned_data"));
});
}
}
// --- Reproduction tests ---
[TestClass]
public class MinimalReproductionTests
{
private static async Task<Exception?> CatchAnyExceptionAsync(Func<Task> action)
{
try { await action(); return null; }
catch (Exception ex) { return ex; }
}
/// <summary>
/// BUG: Querying via a [DbFunction] method on an entity that has OwnsOne().ToJson()
/// throws NullReferenceException in EF Core 10 during query compilation.
///
/// Root location: RelationalQueryableMethodTranslatingExpressionVisitor.AddJsonNavigationBindings
///
/// Works fine in EF Core 9. Works fine in EF Core 10 when using DbSet directly (without DbFunction).
/// </summary>
[TestMethod]
public async Task DbFunction_Plus_OwnsOneToJson_Throws_NullReferenceException()
{
using var ctx = new MinimalDbContext();
// Using the [DbFunction] method (not ctx.Entities directly)
var query = ctx.GetEntities().Select(x => new { x.Id, x.Name, x.OwnedData });
var ex = await CatchAnyExceptionAsync(() => query.ToListAsync());
Assert.IsNotNull(ex, "Expected NullReferenceException but no exception was thrown");
Assert.IsInstanceOfType<NullReferenceException>(ex,
$"Expected NullReferenceException in AddJsonNavigationBindings but got: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}");
}
/// <summary>
/// Confirms the bug does NOT occur when using DbSet directly (without DbFunction).
/// Same entity, same query shape - only difference is DbSet vs DbFunction.
/// This test should fail with SqlException (can't connect to 'fake' server) - NOT NullReferenceException.
/// </summary>
[TestMethod]
public async Task DbSet_Plus_OwnsOneToJson_Does_Not_Throw_NullReferenceException()
{
using var ctx = new MinimalDbContext();
// Same query but using DbSet directly - should NOT crash in query compilation
var query = ctx.Entities.Select(x => new { x.Id, x.Name, x.OwnedData });
var ex = await CatchAnyExceptionAsync(() => query.ToListAsync());
Assert.IsNotNull(ex, "Expected SqlException (connection refused) but no exception was thrown");
Assert.IsNotInstanceOfType<NullReferenceException>(ex,
"Bug is also present in DbSet path - expected only in DbFunction path");
// Expected: Microsoft.Data.SqlClient.SqlException - cannot connect to 'fake'
Console.WriteLine($"Got expected non-null exception: {ex.GetType().Name}: {ex.Message}");
}
/// <summary>
/// Confirms OwnsMany().ToJson() also triggers the bug (not just OwnsOne).
/// </summary>
[TestMethod]
public async Task DbFunction_Plus_OwnsManyToJson_Also_Throws_NullReferenceException()
{
using var ctx = new MinimalDbContextWithOwnsMany();
var query = ctx.GetEntities().Select(x => new { x.Id, x.Items });
var ex = await CatchAnyExceptionAsync(() => query.ToListAsync());
Assert.IsNotNull(ex, "Expected NullReferenceException but no exception was thrown");
Assert.IsInstanceOfType<NullReferenceException>(ex,
$"Expected NullReferenceException in AddJsonNavigationBindings but got: {ex.GetType().Name}: {ex.Message}");
}
}
// --- Variant with OwnsMany ---
public class MinimalEntityWithMany
{
public int Id { get; set; }
public ICollection<MinimalOwnedType> Items { get; set; } = null!;
}
public class MinimalDbContextWithOwnsMany : DbContext
{
public DbSet<MinimalEntityWithMany> Entities { get; set; } = null!;
[DbFunction(Name = "GetEntities", Schema = "dbo")]
public IQueryable<MinimalEntityWithMany> GetEntities() => FromExpression(() => GetEntities());
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
builder.UseSqlServer("Server=fake;Database=fake;Trusted_Connection=yes;");
builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MinimalEntityWithMany>(b =>
{
b.HasKey(x => x.Id);
b.ToTable("MinimalEntitiesWithMany");
b.OwnsMany(x => x.Items, o => o.ToJson("items"));
});
}
}
Stack traces
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.AddJsonNavigationBindings(IEntityType entityType, StructuralTypeProjectionExpression projection, Dictionary`2 propertyExpressions, Dictionary`2 tableMap)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.CreateSelect(IEntityType entityType, TableExpressionBase tableExpressionBase)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerQueryableMethodTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Verbose output
EF Core version
10.0.3
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.Net 10
Operating system
Windows 11
IDE
Visual studio 2026 18.2.1
Bug description
In ef core 10 there is a regression preventing us from updating. When using any entity which has an
OwnsManyorOwnsOnewhich is selected via aDbFunctionan object reference error occurs while compiling the queryYour code
Stack traces
Verbose output
EF Core version
10.0.3
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.Net 10
Operating system
Windows 11
IDE
Visual studio 2026 18.2.1