【问题标题】:Query Postgres Json Field using EF Core 5使用 EF Core 5 查询 Postgres Json 字段
【发布时间】:2021-09-27 01:15:22
【问题描述】:

我有如下表定义

  [Table("MyTable")]
  public class MyTable: BaseEntity
  {
    [Required]
    public string A{ get; set; }

    [Required]
    [Column(TypeName = "json")]
    public string B{ get; set; }
  }

B 列如下所示:

{"Data": [{"Id":"b8a3cbbc-a4d6-4697-8a0b-cb1d15be179d"}]} (aside from Id there are other properties but for brevity I removed them)

在实体框架中,我想匹配所有 MyTable,其中 B 中的 Id 是某个值,A 具有某个值。我已经尝试了很多东西并且得到了很多错误。如何添加到以下代码以实现我想要的?

var results = 
   _repository.Get<MyTable>(_ => _.A == "Something" && _.B = ???);

【问题讨论】:

  • 如果您需要经常查询数据,请创建一个单独的索引表。即使使用 JSON 索引,访问总是比尝试访问普通表慢,无论 RDBMS 是什么。由于该字段实际上包含 object 数据,因此应将其视为实体或值对象。这意味着它需要自己的类型并在 映射之前进行解析。您可以将实体映射到视图,或使用FromSqlRaw/Interpolated“解压”JSON 数据
  • 您问的是如何将某种格式的数据映射到应用程序对象。这显然是映射模型的工作,而不是使用它的 ORM 查询。
  • @PanagiotisKanavos 如何查询数据而不带回表中的所有记录,然后在查询前映射到对象?

标签: postgresql entity-framework-core c#-9.0


【解决方案1】:

你可以使用“EF.Functions.JsonContains”函数,但是B列需要是“jsonb”类型而不是“json”。

    [Required]
    [Column(TypeName = "jsonb")]
    public string B { get; set; }

例子

    var search = "[{\"Id\": \"b8a3cbbc-a4d6-4697-8a0b-cb1d15be179d\"}]";
var results = _context.MyTable2.Where(_ => _.A == "Something" && 
                               EF.Functions.JsonContains(_.B, search));

类似的答案HERE

此外,您可以键入查询并使用 Dapper。 示例

 with temp AS(
  select t."Id", t."A", json_array_elements(t."B"->'Data') as B1 from "MyTable"  t
  )
  select * from temp t
  where 
  t."A"='Something' and
  t.b1->>'Id'='b9a3cbbc-a4d6-4697-8a0b-cb1d15be179a'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2014-07-05
    • 1970-01-01
    • 2021-12-26
    • 2017-04-03
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多