npgsql.EntityFrameworkCore.PostgreSQL - 使用 json 参数执行函数不起作用

pau*_*sim 1 c# npgsql docker entity-framework-core linux-containers

数据库:Postgresql

ORM:带有 Npgsql.EntityFrameworkCore.PostgreSQL 的实体框架核心

尝试调用以下函数将产品列表作为 json 传递

dbContext.product.FromSqlRaw("SELECT pa.usp_set_product({0})", productjson).ToList();
Run Code Online (Sandbox Code Playgroud)

返回错误为:“42883:函数 pa.usp_set_product(text) 不存在”

然后尝试下面

dbContext.product.FromSqlRaw(@"SELECT pa.usp_set_product('" + productjson+ "')").ToList();
Run Code Online (Sandbox Code Playgroud)

返回错误:“输入字符串的格式不正确”

然后尝试下面效果很好

 using (var cmd = new NpgsqlCommand(@"SELECT pa.usp_set_product(@productjson)", conn))
   {
    cmd.Parameters.Add(new NpgsqlParameter("productjson", NpgsqlDbType.Json) { Value = productjson});
    cmd.ExecuteNonQuery();
   }
Run Code Online (Sandbox Code Playgroud)

任何想法,请-

  1. 为什么带有 JSON 参数的 FromSqlRaw 不起作用
  2. 使用 NpgsqlCommand 是否有任何缺点 - 它是否支持 Linux 容器(docker)

谢谢,

@保罗

Sha*_*sky 5

当您在 FromSqlRaw 中包含参数值时,它将作为默认对应的 PG 类型发送;我假设你的productjson是一个 .NET 字符串,它映射到 PG text,而不是json. 结果与使用 NpgsqlCommand 的较低级别代码相同,但未指定NpgsqlDbType.Json.

EF Core 还允许您传递 DbParameter 实例而不是原始值,因此您应该能够执行以下操作:

var jsonParam = new NpgsqlParameter("productjson", NpgsqlDbType.Json);

dbContext.product.FromSqlRaw("SELECT pa.usp_set_product(@jsonParam)", jsonParam).ToList();

此文档页面上提供了更多信息。

注意:切勿将字符串连接或插入到 FromSqlRaw 的 SQL 中 - 这容易受到 SQL 注入的攻击。仔细阅读EF 文档以获取更多信息。

注意2:考虑使用 PostgreSQLjsonb类型而不是json. 您可以在此处了解差异。