【问题标题】:C# SQL Server to JSON with key groupsC# SQL Server 到带有密钥组的 JSON
【发布时间】:2021-12-28 08:25:27
【问题描述】:

我的这张表基本上是翻译:

Key        CultureId     Txt
$HELLO     en-GB         Hello
$HELLO     pt-BR         Olá
$WELCOME   en-GB         Welcome
$WELCOME   pt-BR         Olá

还有一个选择:

Select Key, CultureId, Txt 
From Xlations 
Order by Key

这是一个端点休息 api,所以我想要一个类似的结果

{
   "$HELLO":{
      "en-GB":"Hello",
      "pt-BR":"Olá"
   },
   "$WELCOME":{
      "en-GB":"Bem Vindo",
      "pt-BR":"Welcome"
   }
}

因此,没有数组的键,完全在字段键将是分配翻译的父对象的对象中。

我知道如何通过在我的代码上创建一些迭代来做到这一点,但我想知道是否有一些速记,因为我不想让我的代码因迭代和嵌套迭代而变得庞大而复杂。不确定这样的事情是否可能,但是:有人知道一些简单易行的方法吗?

【问题讨论】:

标签: c# sql-server


【解决方案1】:

JSON 输出通常使用FOR JSON 子句生成。在您的情况下,所需的 JSON 输出具有可变键名,因此 FOR JSON 可能不是一个选项。但是,如果 SQL Server 版本是 2017 或更高版本,您可以尝试使用字符串连接和聚合手动生成 JSON。此外,正如@Charlieface 评论的那样,使用STRING_ESCAPE() 转义生成的文本。

测试表:

SELECT *
INTO Xlations
FROM (VALUES
   (N'$HELLO',   N'en-GB', N'Hello'),
   (N'$HELLO',   N'pt-BR', N'Olá'),
   (N'$WELCOME', N'en-GB', N'Welcome'),
   (N'$WELCOME', N'pt-BR', N'Bem Vindo')
) v ([Key], CultureId, Txt)

声明:

SELECT CONCAT(
   N'{',
   STRING_AGG(CONCAT(N'"', STRING_ESCAPE([Key], 'json'), N'":', [Value]), N','),
   N'}'
) AS Json
FROM (
   SELECT DISTINCT x.[Key], a.[Value]
   FROM Xlations x
   OUTER APPLY (
      SELECT CONCAT(
         N'{',
         STRING_AGG(CONCAT(N'"', STRING_ESCAPE(CultureId, 'json'), N'":"', STRING_ESCAPE(Txt, 'json'), N'"'), N','),
         N'}'
      ) AS [Value]
      FROM Xlations
      WHERE [Key] = x.[Key]
   ) a
) t

结果:

{
   "$HELLO":{"en-GB":"Hello","pt-BR":"Olá"},
   "$WELCOME":{"en-GB":"Welcome","pt-BR":"Bem Vindo"}
}

【讨论】:

    【解决方案2】:

    您不能使用您的 sql 函数来执行此操作,您必须手动执行此操作。

    SELECT CONCAT('{',string_agg(jsoncol,','),'}') Json
    FROM
       (SELECT '1' AS col, CONCAT('"',[key],'"',':{' + string_agg(jsoncol,',') ,'}') AS jsoncol
        FROM 
           (SELECT [key],CONCAT('"',CultureId,'":"',txt ,'"') AS jsoncol FROM tb) t
        GROUP BY [key]) t
    GROUP BY col
    

    dbfiddle<>uk中的演示

    【讨论】:

    • 别忘了STRING_ESCAPE
    【解决方案3】:

    The answer given by @Zhorov 很好,但您可以通过只查询表一次、聚合然后再次聚合来改进它。

    这应该比相关子查询更高效。

    SELECT CONCAT(
       N'{',
       STRING_AGG(CONCAT(N'"', STRING_ESCAPE([Key], 'json'), N'":', [Value]), N','),
       N'}'
    ) AS Json
    FROM (
       SELECT x.[Key], CONCAT(
             N'{',
             STRING_AGG(CONCAT(N'"', STRING_ESCAPE(CultureId, 'json'), N'":"', STRING_ESCAPE(Txt, 'json'), N'"'), N','),
             N'}'
          ) AS [Value]
       FROM Xlations x
       GROUP BY x.[Key]
    ) t
    

    db<>fiddle

    【讨论】:

      猜你喜欢
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 2016-05-10
      相关资源
      最近更新 更多