Bug description
#38155 added a !_parameterize check to ExpressionTreeFuncletizer so that EF.Constant, EF.Parameter and EF.MultipleParameters throw in compiled queries and query filters. Query filters are also funcletized with parameterize: false. As a result, ordinary non-compiled queries now fail when an entity's query filter uses one of these methods on a context property. This pattern worked before #38155.
Repro
public class BlogContext(DbContextOptions options) : DbContext(options)
{
public int TenantId { get; set; } = 1;
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Blog>()
.HasQueryFilter(e => e.TenantId == EF.Parameter(TenantId)); // same with EF.Constant(TenantId)
}
context.Set<Blog>().ToList();
Before #38155: the query runs and returns only the rows for TenantId == 1.
After #38155:
System.InvalidOperationException: 'EF.Parameter<T>' is not supported when using compiled queries or query filters.
at ExpressionTreeFuncletizer.<VisitMethodCall>g__HandleParameter|40_1(...)
at NavigationExpandingExpressionVisitor.ApplyQueryFilter(...)
Your code
The following test can be added to AdHocQueryFiltersQueryTestBase. It fails on main with InvalidOperationException: 'EF.Parameter<T>' is not supported when using compiled queries or query filters. and passes when the !_parameterize checks added in #38155 are removed.
[Fact]
public virtual async Task Non_compiled_query_with_EF_Parameter_in_query_filter_over_context_property()
{
var contextFactory = await InitializeNonSharedTest<Context_ParameterFilter>(seed: c => c.SeedAsync());
using var context = contextFactory.CreateDbContext();
Assert.Equal([1, 2], context.Set<Entity>().OrderBy(e => e.Id).Select(e => e.Id).ToList());
}
protected class Context_ParameterFilter(DbContextOptions options) : DbContext(options)
{
public int TenantId { get; set; } = 1;
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Entity>()
.HasQueryFilter(e => e.TenantId == EF.Parameter(TenantId)); // same with EF.Constant(TenantId)
public Task SeedAsync()
{
AddRange(
new Entity { Id = 1, TenantId = 1 },
new Entity { Id = 2, TenantId = 1 },
new Entity { Id = 3, TenantId = 2 });
return SaveChangesAsync();
}
}
public class Entity
{
public int Id { get; set; }
public int TenantId { get; set; }
}
Note: the existing tests Query_filter_with_EF_Parameter_throws and Query_filter_with_EF_Constant_throws use this same context-property pattern and would need to be removed or changed.
EF Core version
11 RC1
Bug description
#38155 added a
!_parameterizecheck toExpressionTreeFuncletizerso thatEF.Constant,EF.ParameterandEF.MultipleParametersthrow in compiled queries and query filters. Query filters are also funcletized withparameterize: false. As a result, ordinary non-compiled queries now fail when an entity's query filter uses one of these methods on a context property. This pattern worked before #38155.Repro
Before #38155: the query runs and returns only the rows for
TenantId == 1.After #38155:
Your code
The following test can be added to
AdHocQueryFiltersQueryTestBase. It fails onmainwithInvalidOperationException: 'EF.Parameter<T>' is not supported when using compiled queries or query filters.and passes when the!_parameterizechecks added in #38155 are removed.Note: the existing tests
Query_filter_with_EF_Parameter_throwsandQuery_filter_with_EF_Constant_throwsuse this same context-property pattern and would need to be removed or changed.EF Core version
11 RC1