Bug description
On EF Core 10, a global query filter that reads a navigation column via an inline array +
.Any(...) produces invalid SQL: the join-derived table for that navigation projects only the join
key (Id), while the filter's EXISTS clause still references another column from it (ServiceId).
Regression: same code works on EF Core 9.x (tested with 9.0.18 on net10.0), fails on EF Core
10.0.0–10.0.10. Also reproduced on PostgreSQL and MySQL (same error shape). Not caused by named
query filters — classic HasQueryFilter(lambda) reproduces it.
Expected: query returns ["ok"].
Workaround (EF10): avoid the inline collection — Scope.AuthorizedServiceIds.Contains(c.Parent.ServiceId) works.
Likely root cause (source reading on v10.0.10, SqlTreePruner.PruneValues): the inline array
becomes a ValuesExpression whose row value is a ColumnExpression (p0.ServiceId). EF10's
PruneValues (#36159) copies row values without
Visit(), so embedded column refs are never registered → join subquery pruned to Id only.
Related: #34954 (same territory, different failure).
Runnable projects (dotnet run, logs SQL):
Your code
public class Parent
{
public int Id { get; set; }
public int ServiceId { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; } = null!;
public string Label { get; set; } = "";
}
public static class Scope
{
public static List<int> AuthorizedServiceIds { get; set; } = [];
}
public class ReproContext(DbContextOptions<ReproContext> options) : DbContext(options)
{
public DbSet<Parent> Parents => Set<Parent>();
public DbSet<Child> Children => Set<Child>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>().HasQueryFilter(
p => Scope.AuthorizedServiceIds.Contains(p.ServiceId));
// Inline array of a navigation column — this is the trigger.
modelBuilder.Entity<Child>().HasQueryFilter(c =>
new int?[] { c.Parent.ServiceId }
.Any(id => id.HasValue && Scope.AuthorizedServiceIds.Contains(id.Value)));
}
}
Scope.AuthorizedServiceIds = [10];
// Seed: Parent { Id = 1, ServiceId = 10 }, Child { ParentId = 1, Label = "ok" }
var results = await context.Children.AsNoTracking().Select(c => c.Label).ToListAsync(); // throws
Stack traces
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such column: p0.ServiceId'.
at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements()+MoveNext()
at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
Same shape on PostgreSQL (column p0.ServiceId does not exist) and MySQL (Unknown column 'p0.ServiceId').
Verbose output
EF Core 10 — failing SQL (SQLite):
SELECT "c"."Label"
FROM "Children" AS "c"
INNER JOIN (
SELECT "p"."Id"
FROM "Parents" AS "p"
WHERE "p"."ServiceId" = 10
) AS "p0" ON "c"."ParentId" = "p0"."Id"
WHERE EXISTS (
SELECT 1
FROM (SELECT "p0"."ServiceId" AS "Value") AS "v"
WHERE "v"."Value" = 10)
p0 projects only Id, but the EXISTS still reads p0.ServiceId.
EF Core 9.0.18 — same code, working SQL (SQLite):
SELECT "c"."Label"
FROM "Children" AS "c"
INNER JOIN (
SELECT "p"."Id", "p"."ServiceId"
FROM "Parents" AS "p"
WHERE "p"."ServiceId" = 10
) AS "p0" ON "c"."ParentId" = "p0"."Id"
WHERE EXISTS (
SELECT 1
FROM (SELECT "p0"."ServiceId" AS "Value") AS "v"
WHERE "v"."Value" = 10)
Console output (EF10): FAIL — SqliteException: SQLite Error 1: 'no such column: p0.ServiceId'.
Console output (EF9): OK — ok
EF Core version
10.0.10 (appeared in 10.0.0)
Database provider
Microsoft.EntityFrameworkCore.Sqlite 10.0.10 (primary repro above).
Also reproduced on Npgsql 10.0.0 (PostgreSQL) and Microting.EntityFrameworkCore.MySql 10.0.10 (MySQL).
Target framework
net10.0
Operating system
Linux (Ubuntu)
IDE
No response
Bug description
On EF Core 10, a global query filter that reads a navigation column via an inline array +
.Any(...)produces invalid SQL: the join-derived table for that navigation projects only the joinkey (
Id), while the filter'sEXISTSclause still references another column from it (ServiceId).Regression: same code works on EF Core 9.x (tested with 9.0.18 on net10.0), fails on EF Core
10.0.0–10.0.10. Also reproduced on PostgreSQL and MySQL (same error shape). Not caused by named
query filters — classic
HasQueryFilter(lambda)reproduces it.Expected: query returns
["ok"].Workaround (EF10): avoid the inline collection —
Scope.AuthorizedServiceIds.Contains(c.Parent.ServiceId)works.Likely root cause (source reading on v10.0.10,
SqlTreePruner.PruneValues): the inline arraybecomes a
ValuesExpressionwhose row value is aColumnExpression(p0.ServiceId). EF10'sPruneValues(#36159) copies row values withoutVisit(), so embedded column refs are never registered → join subquery pruned toIdonly.Related: #34954 (same territory, different failure).
Runnable projects (
dotnet run, logs SQL):Your code
Stack traces
Same shape on PostgreSQL (
column p0.ServiceId does not exist) and MySQL (Unknown column 'p0.ServiceId').Verbose output
EF Core 10 — failing SQL (SQLite):
p0projects onlyId, but theEXISTSstill readsp0.ServiceId.EF Core 9.0.18 — same code, working SQL (SQLite):
Console output (EF10):
FAIL — SqliteException: SQLite Error 1: 'no such column: p0.ServiceId'.Console output (EF9):
OK — okEF Core version
10.0.10 (appeared in 10.0.0)
Database provider
Microsoft.EntityFrameworkCore.Sqlite 10.0.10 (primary repro above).
Also reproduced on Npgsql 10.0.0 (PostgreSQL) and Microting.EntityFrameworkCore.MySql 10.0.10 (MySQL).
Target framework
net10.0
Operating system
Linux (Ubuntu)
IDE
No response