【问题标题】:Transform table to json object SQL like dictionary?将表转换为像字典一样的 json 对象 SQL?
【发布时间】:2021-12-14 02:34:01
【问题描述】:

我有一个包含两列的表,我正在尝试将查询转换为具有键值对的对象,以将其保存到 c# 中的字典中。

C# 代码将 Json 对象转换为字典

string JsonDictionary;
JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonDictionary);

我在 sql server 中的表:

我的查询:

SELECT 
    C.[Key]
    ,C.[Value]
FROM dbo.Settings C
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

输出查询:

{
    "Key": "userName",
    "Value": "userNameValue"
},
{
    "Key": "password",
    "Value": "passwordValue"
},
{
    "Key": "domain",
    "Value": "domainValue"
}

预期输出:

{
    "userName": "userNameValue",
    "password": "passwordValue",
    "domain": "domainValue"
}

我已搜索但找不到解决方案

【问题讨论】:

  • 那么,您想在 SQL 中执行此操作吗?或者您是否愿意从表中选择值,然后在 C# 中进行简单的转换?
  • 我正在尝试从 SQL 查询中获取它,但我愿意从 c# 代码中获取它。
  • 对任何数据库内容使用实体框架。比手动做事要好得多

标签: c# sql json sql-server


【解决方案1】:

SQL Server 不能很好地处理动态键。您需要使用动态 SQL 来执行此操作:

DECLARE @paths nvarchar(max) = (
    SELECT STRING_AGG(
      QUOTENAME(c.[Key]) + N' = MAX(CASE WHEN c.[Key] = ' + QUOTENAME(c.[Key], '''') + ' THEN c.Value END)', ',
    ')

    FROM (SELECT DISTINCT [Key] FROM dbo.Settings) C
);

DECLARE @sql nvarchar(max) = N'
SELECT 
    ' + @cols + '
FROM dbo.Settings C
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
';

PRINT @sql; --for testing

EXEC sp_executesql @sql;

【讨论】:

    【解决方案2】:

    你有没有尝试过改变你的想法?

    create table dbo.Settings (
      [Key] nvarchar(20),
      [Value] nvarchar(20)
    );
    
    insert dbo.Settings ([Key], [Value]) values
      ('userName', 'userNameValue'),
      ('password', 'passwordValue'),
      ('domain', 'domainValue');
    
    select [userName], [password], [domain]
    from dbo.Settings src
    pivot (max([Value]) for [Key] in ([userName], [password], [domain])) pvt
    for json path, without_array_wrapper;
    

    这会产生 JSON 结果:

    {
        "userName": "userNameValue",
        "password": "passwordValue",
        "domain": "domainValue"
    }
    

    【讨论】:

      【解决方案3】:

      由于 Post Owner 对 C# 解决方案开放。

      当数据来自List&lt;T&gt;时,可以使用Enumerable.ToDictionary转换为Dictionary&lt;string, string&gt;

      来自列表

      using System.Linq;
      
      // Result from DB
      List<KeyValue> data = new List<KeyValue>
      {
          new KeyValue
          {
              Key = "userName", Value = "userNameValue"
          },
          new KeyValue
          {
              Key = "password", Value = "passwordValue"
          },
          new KeyValue
          {
              Key = "domain", Value = "domainValue"
          }
      };
              
      Dictionary<string, string> dict = data.ToDictionary(x => x.Key, x => x.Value);
      
      foreach (var kvp in dict)
      {
          Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
      }
      
      public class KeyValue
      {
          public string Key {get;set;}
          public string Value {get;set;}
      }
      

      Sample program (From List&lt;T&gt;)


      当数据来自DataTable 时,您使用dt.Rows 进行迭代并添加到Dictionary&lt;string, string&gt;

      来自DataTable

      using System.Data;
      
      #region Mock DataTable
      DataTable dt = new DataTable();
      dt.Columns.Add("Key", typeof(string));
      dt.Columns.Add("Value", typeof(string));
              
      var rowOne = dt.NewRow();
      rowOne["Key"] = "userName";
      rowOne["Value"] = "userNameValue";
              
      var rowTwo = dt.NewRow();
      rowTwo["Key"] = "password";
      rowTwo["Value"] = "passwordValue";
              
      var rowThree = dt.NewRow();
      rowThree["Key"] = "domain";
      rowThree["Value"] = "domainValue";
              
      dt.Rows.Add(rowOne);
      dt.Rows.Add(rowTwo);
      dt.Rows.Add(rowThree);
      #endregion
              
      Dictionary<string, string> dict = new Dictionary<string, string>();
              
      foreach(DataRow row in dt.Rows)
      {
          dict.Add(row["Key"].ToString(), row["Value"].ToString());
      }
                      
      foreach (var kvp in dict)
      {
          Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
      }
      

      Sample program (From DataTable)

      【讨论】:

        【解决方案4】:

        如果你使用 EntityFramework,你会这样做:

        var dict = _context.Settings.ToDictionary(k => k.Key, v => v.Value);
        

        如果你使用 Dapper,那么它看起来像这样:

        var dict = conn.Query<KeyValuePair<string, string>>("SELECT Key, Value FROM Settings")
          .ToDictionary(k => k.Key, v => v.Value);
        

        此处使用 Northwind 数据库的示例:https://dotnetfiddle.net/22sZ7H

        【讨论】:

          【解决方案5】:

          使用串联构造一个简单的json对象

          DECLARE
              @Settings VARCHAR(MAX);
          
          SELECT 
              @Settings = COALESCE(@Settings + ', ', '') + '"' + C.[Key] + '":"' +  C.[Value] + '"'
          FROM dbo.Settings C
          
          SELECT CONCAT('{', @Settings, '}')
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-04-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-04-27
            • 1970-01-01
            • 2019-04-02
            相关资源
            最近更新 更多