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

npgsql.EntityFrameworkCore.PostgreSQL - execute function with json parameter is not working

数据库:Postgresql

ORM:Entity framework 核心 Npgsql.EntityFrameworkCore.PostgreSQL

尝试调用以下功能传递产品列表作为 json

dbContext.product.FromSqlRaw("SELECT pa.usp_set_product({0})", productjson).ToList();

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

然后尝试以下

dbContext.product.FromSqlRaw(@"SELECT pa.usp_set_product('" + productjson+ "')").ToList();

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

然后试了下效果不错

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

任何想法,请-

  1. 为什么带有 JSON 参数的 FromSqlRaw 不起作用
  2. 使用 NpgsqlCommand 有什么缺点吗 - 它支持 Linux-container(docker)

谢谢,

@保罗

您没有使用 LINQ 进行查询有什么原因吗? 它更简单、使用广泛,并且针对您需要的大多数查询进行了优化。 如果您创建一个 Product 实体,它看起来像这样:

DbContext.Products.Add(new Product() { ProductName = "Test Product", Weight = 5, ... }
await DbContext.SaveChangesAsync();

然后,如果您想要检索 ID 为 productId 的产品:

Product product = await DbContext.Products.FirstOrDefaultAsync(p => p.Id == productId);

您需要所有已删除的产品吗?

List<Product> deletedProducts = await DbContext.Products.Where(p => p.DeletionTime != null).ToListAsync();

(这些示例取决于您向 Product 实体添加所需的属性,例如 Id 和 DeletionTime)

当你在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();

可获得更多信息 on this doc page

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

注意 2:考虑使用 PostgreSQLjsonb 类型而不是 json。您可以阅读差异 here.