【问题标题】:npgsql.EntityFrameworkCore.PostgreSQL - execute function with json parameter is not workingnpgsql.EntityFrameworkCore.PostgreSQL - 带有 json 参数的执行函数不起作用
【发布时间】:2020-10-13 22:28:33
【问题描述】:

数据库:Postgresql

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

试图将下面的函数调用为 json 传递产品列表

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

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

然后在下面尝试

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

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

然后在下面尝试,效果很好

 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)

谢谢,

@保罗

【问题讨论】:

    标签: c# docker entity-framework-core npgsql linux-containers


    【解决方案1】:

    当你在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:考虑使用 PostgreSQL jsonb 类型而不是 json。您可以阅读 here 的差异。

    【讨论】:

      【解决方案2】:

      您没有使用 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)

      【讨论】:

      • OP 询问了执行存储函数,此处使用 LINQ 的建议不相关。
      • 也许他不知道 LINQ,我不明白他为什么要写这么简单的原始查询。
      • 他不是真的在写查询,他是在调用函数……我们不知道里面有什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多