EF 2.1 + Npgsql + ExecuteSqlCommand = "$1" 处或附近的语法错误

EF 2.1 + Npgsql + ExecuteSqlCommand = syntax error at or near "$1"

自 EF Core 2.1 起,检查 SQL 以进行注入。没关系。

但是将参数传递给 ExecuteSqlCommand 的正确方法是什么?

var content = "whatever";

...

var command = @"NOTIFY test, '{0}'";
ctx.Database.ExecuteSqlCommand(command, content);

Executes "NOTIFY test, '@p0'". That's wrong.

ctx.Database.ExecuteSqlCommand($"NOTIFY test, {content}");

Message: 42601: syntax error at or near "".

var command = $"NOTIFY test, {content}";
ctx.Database.ExecuteSqlCommand(command);

Works, but "warning EF1000: The SQL expression passed to 'FromSql' embeds data that will not be parameterized. (...)". Wrong. That's exactly what I'm trying to fix.

var command = @"NOTIFY test, @Content";
ctx.Database.ExecuteSqlCommand(command, new SqlParameter("@Content", content));

InvalidCastException: "value must be an NpgsqlParameter." Oh, well.

var command = @"NOTIFY test, @Content";
ctx.Database.ExecuteSqlCommand(command, new NpgsqlParameter("@Content", content));
(or)
ctx.Database.ExecuteSqlCommand(command, new NpgsqlParameter("Content", content));

Message: 42601: syntax error at or near "". SERIOUSLY?

var command = @"NOTIFY test, {0}";
(or)
var command = @"NOTIFY test, ";
(or)
var command = @"NOTIFY test, @Content";
ctx.Database.ExecuteSqlCommand(command, new NpgsqlParameter{Value = content});

Message: 42601: syntax error at or near "". I quit.

我是不是漏掉了什么?

PostgreSQL 根本不支持 NOTIFY 语句中的参数...如果您尝试使用常规 DML,例如 SELECTINSERT 一切都应该有效.

如果你真的想参数化通知,你仍然可以进行客户端字符串插值,但一定要清理用户输入,否则你会 SQL 注入。

我想我漏掉了一些东西:

查看文档时(http://www.npgsql.org/doc/index.html) 有这样的样本

此外,您能否展示示例 table 结构?

var connString = "Host=myserver;Username=mylogin;Password=mypass;Database=mydatabase";

using (var conn = new NpgsqlConnection(connString))
{
    conn.Open();

    // Insert some data
    using (var cmd = new NpgsqlCommand())
    {
        cmd.Connection = conn;
        cmd.CommandText = "INSERT INTO data (some_field) VALUES (@p)";
        cmd.Parameters.AddWithValue("p", "Hello world");
        cmd.ExecuteNonQuery();
    }

    // Retrieve all rows
    using (var cmd = new NpgsqlCommand("SELECT some_field FROM data", conn))
    using (var reader = cmd.ExecuteReader())
        while (reader.Read())
            Console.WriteLine(reader.GetString(0));
}
You can find more info about the ADO.NET API in the MSDN docs or in many tutorials on the Internet.

基于 "NOTIFY test, " 我不知道你想做什么