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();
}
任何想法,请-
- 为什么带有 JSON 参数的 FromSqlRaw 不起作用
- 使用 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.
数据库: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();
}
任何想法,请-
- 为什么带有 JSON 参数的 FromSqlRaw 不起作用
- 使用 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.