我正在为. NET 3.1上的EF Core而激动不已。我有以下代码摘录:
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));
}
除了缺少这个方法的上下文之外,让我困惑的是Fluent API版本和LINQ查询表达式版本都能按预期工作,在DB中返回12个条目,相反,插值和原始SQL都无法返回0个条目。
请注意:这并不是因为我得到了一个异常或任何错误。2他们只是返回0个结果,就好像查询是错误的。
为了进行原始测试,我设置了一个断点,复制了 * name * 值,并直接在pgAdmin中执行查询。
这是您在代码中看到的4个查询的(相当复杂的)调试输出:
#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)
我看到LINQ/Fluent版本在一个我无法理解的相当奇怪的SQL中传播,但不幸的是,我也不明白为什么代码没有在原始/插入的SQL中正确扩展我的参数。
谢谢你的提示!
1条答案
按热度按时间dm7nw8vv1#
好的,
我知道了!而在这同时ErikEJ在评论中回答了。
TL; DR:基本上,您需要将通配符包括到原始C#变量中
在我的原始代码中有许多问题:
1.将参数扩展为like语句在普通Postgres中甚至不起作用。让我来解释一下:当我用pgAdim测试原始查询时,我编写了直接查询,假设作者的名字是 * matteo *,我测试了如下查询:
无论如何,任何DB连接层都可能面向预处理语句而不是原始查询,因此我在SQL中尝试了以下新代码:
这在SQL中也会失败!
1.在普通SQL中作为预准备语句的工作方式是:
所以我试了这个代码:
不幸的是,这又失败了。
1.我的代码失败的原因如下:EF Core * 已经将 * 从C#字符串转换为SQL文本类型,因此不需要单引号!!!我的代码类似于:
所以问题的解决办法一直是: