I'm wetting my feet with EF Core on .NET 3.1. I've the following code excerpt:
public static async Task<Task> getWithName(HttpContext c) {
var name = c.Request.RouteValues["name"].ToString();
// with API - WORKS!
var authors = await DB.Authors.Where(a => a.first_name.Contains(name)).ToListAsync();
// with raw SQL interpolated - BROKEN
var authors2 = await DB.Authors.FromSqlInterpolated($"SELECT * FROM author WHERE first_name like '%{name}%'").ToListAsync();
// with raw SQL parametrized - BROKEN
var authors3 = await DB.Authors.FromSqlRaw("SELECT * FROM author WHERE first_name like '%{0}%'", name).ToListAsync();
// with LINQ expressions - WORKS!
var authors4 = await (from a in DB.Authors where a.first_name.Contains(name) select a).ToListAsync();
c.Response.ContentType = "application/json";
return c.Response.WriteAsync(Serialize(authors));
}
beside the missing context around this method, what confuses me is that both the fluent API version and the LINQ query expression version work as expected, returning the 12 items in the DB. On the opposite both the interpolated and raw SQL fail returning 0 items.
Plese, mind: it is not that I get an exception or any erorr. They simply return 0 results as if the query was wrong.
To make a raw test, I've just put a breakpoint, copied the name value and performed the query straight into pgAdmin. The query works as expected, returning the same 12 items.
This is the (rather complex) debug output of the 4 queries you see in the code:
#this is the DB init debug output
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.1.4 initialized 'AuthorContext' using provider
'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
#this is the fluent API query, which works
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (14ms) [Parameters=[@__name_0='?'], CommandType='Text', CommandTimeout='30']
SELECT a.id, a.first_name, a.last_name, a.nationality
FROM public.author AS a
WHERE (@__name_0 = '') OR (STRPOS(a.first_name, @__name_0) > 0)
#this is the raw SQL, which fails
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (7ms) [Parameters=[p0='?'], CommandType='Text', CommandTimeout='30']
SELECT * FROM author WHERE first_name like '%@p0%'
#this is the interpolated SQL, which fails too
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[p0='?'], CommandType='Text', CommandTimeout='30']
SELECT * FROM author WHERE first_name like '%@p0%'
#this is the LINQ expression query, which works
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[@__name_0='?'], CommandType='Text', CommandTimeout='30']
SELECT a.id, a.first_name, a.last_name, a.nationality
FROM public.author AS a
WHERE (@__name_0 = '') OR (STRPOS(a.first_name, @__name_0) > 0)
I see that the LINQ/Fluent version transpiles in a rather strange SQL I'm unable to understand, but unfortunately I do not also understand why the code doesn't expand correctly my param in the raw/interpolated SQL.
Thank you for any hint!