Skip to content

Add EF.Parameter to force parameterization in query #28151

Closed
@roji

Description

@roji

In F#, closure parameters are integrated into the query expression tree as constant nodes - see dotnet/fsharp#12841 for the full details. This means that by default, all EF queries generate SQL with constants rather than parameters.

A workaround is to use a F# ref, which gets properly parameterized by EF Core:

let i = ref 8
db.Events.Where(fun x -> x.Data = i.Value).ToList();

However, while this works well with local variables, it's problematic for use with function parameters, since the parameter needs to be typed as Ref<T> (it isn't great to require people to change method signatures just so that an EF query inside get properly parameterized). Note that the variable name is also lost, so the SQL contains @__Value_0.

We could introduced an EF.Param() mechanism, which is identified by EF Core and forces parameterization. The same mechanism could be used in C# to force parameterization for better perf when two queries use different constants, without needing to extract a variable:

var query1 = await ctx.Blogs.Where(b => b.Name == EF.Param("foo")).ToListAsync();
...
var query2 = await ctx.Blogs.Where(b => b.Name == EF.Param("bar")).ToListAsync();

EF.Param could optionally also accept the SQL parameter name, to produce more readable SQL queries.

/cc @dsyme @NinoFloris

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions