Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/EFCore/EFCore.baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -3970,6 +3970,9 @@
{
"Member": "static string DuplicateTrigger(object? trigger, object? entityType, object? conflictingEntityType);"
},
{
"Member": "static string EFMethodNotSupportedInCompiledQueries(object? methodName);"
},
{
"Member": "static string EFMethodWithNonEvaluatableArgument(object? methodName);"
},
Expand Down
8 changes: 8 additions & 0 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,9 @@
<data name="EFConstantNotSupportedInPrecompiledQueries" xml:space="preserve">
<value>The 'EF.Constant&lt;T&gt;' method is not supported when using precompiled queries.</value>
</data>
<data name="EFMethodNotSupportedInCompiledQueries" xml:space="preserve">
<value>'{methodName}' is not supported when using compiled queries or query filters.</value>
Comment thread
roji marked this conversation as resolved.
</data>
<data name="EFMethodWithNonEvaluatableArgument" xml:space="preserve">
<value>The '{methodName}' method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities.</value>
</data>
Expand Down
10 changes: 10 additions & 0 deletions src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,11 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall)
throw new InvalidOperationException(CoreStrings.EFConstantNotSupportedInPrecompiledQueries);
}

if (!_parameterize)
{
throw new InvalidOperationException(CoreStrings.EFMethodNotSupportedInCompiledQueries("EF.Constant<T>"));
}

var argument = Visit(methodCall.Arguments[0], out var argumentState);

if (!argumentState.IsEvaluatable)
Expand Down Expand Up @@ -1118,6 +1123,11 @@ static bool TryUnwrapSpanImplicitCast(Expression expression, [NotNullWhen(true)]

Expression HandleParameter(MethodCallExpression methodCall, string methodName)
{
if (!_parameterize)
{
throw new InvalidOperationException(CoreStrings.EFMethodNotSupportedInCompiledQueries(methodName));
}
Comment thread
roji marked this conversation as resolved.

var argument = Visit(methodCall.Arguments[0], out var argumentState);

if (!argumentState.IsEvaluatable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,4 +850,52 @@ public class Entity38132
}

#endregion

#region 38151

[ConditionalFact]
public virtual async Task Query_filter_with_EF_Constant_throws()
{
var contextFactory = await InitializeNonSharedTest<Context38151_Constant>();
using var context = contextFactory.CreateDbContext();

var message = Assert.Throws<InvalidOperationException>(() => context.Set<Entity38151>().ToList()).Message;
Assert.Equal(CoreStrings.EFMethodNotSupportedInCompiledQueries("EF.Constant<T>"), message);
}

protected class Context38151_Constant(DbContextOptions options) : DbContext(options)
{
public int TenantId { get; set; } = 1;

protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Entity38151>()
.HasQueryFilter(e => e.TenantId == EF.Constant(TenantId));
}

[ConditionalFact]
public virtual async Task Query_filter_with_EF_Parameter_throws()
{
var contextFactory = await InitializeNonSharedTest<Context38151_Parameter>();
using var context = contextFactory.CreateDbContext();

var message = Assert.Throws<InvalidOperationException>(() => context.Set<Entity38151>().ToList()).Message;
Assert.Equal(CoreStrings.EFMethodNotSupportedInCompiledQueries("EF.Parameter<T>"), message);
}

protected class Context38151_Parameter(DbContextOptions options) : DbContext(options)
{
public int TenantId { get; set; } = 1;

protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Entity38151>()
.HasQueryFilter(e => e.TenantId == EF.Parameter(TenantId));
}

public class Entity38151
{
public int Id { get; set; }
public int TenantId { get; set; }
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,32 @@ await asyncSingleResultQueryWithCancellationToken(
"CHOPS", "CONSH", default));
}

[ConditionalFact]
public virtual void Compiled_query_with_EF_Constant_throws()
{
var query = EF.CompileQuery(
(NorthwindContext context) => context.Customers.Where(c => c.CustomerID == EF.Constant("ALFKI")));

using var context = CreateContext();

var message = Assert.Throws<InvalidOperationException>(() => query(context).ToList()).Message;
Assert.Equal(CoreStrings.EFMethodNotSupportedInCompiledQueries("EF.Constant<T>"), message);
}

[ConditionalFact]
public virtual void Compiled_query_with_EF_Parameter_throws()
{
var customerID = "ALFKI";

var query = EF.CompileQuery(
(NorthwindContext context) => context.Customers.Where(c => c.CustomerID == EF.Parameter(customerID)));

using var context = CreateContext();

var message = Assert.Throws<InvalidOperationException>(() => query(context).ToList()).Message;
Assert.Equal(CoreStrings.EFMethodNotSupportedInCompiledQueries("EF.Parameter<T>"), message);
}

protected async Task<int> CountAsync<T>(IAsyncEnumerable<T> source)
{
var count = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,12 @@ ORDER BY [c].[CustomerID]
""");
}

public override void Compiled_query_with_EF_Constant_throws()
=> base.Compiled_query_with_EF_Constant_throws();

public override void Compiled_query_with_EF_Parameter_throws()
=> base.Compiled_query_with_EF_Parameter_throws();

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Loading