将表转换为像字典一样的 json 对象 SQL?
Posted
技术标签:
【中文标题】将表转换为像字典一样的 json 对象 SQL?【英文标题】:Transform table to json object SQL like dictionary? 【发布时间】: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# 代码中获取它。 对任何数据库内容使用实体框架。比手动做事要好得多 【参考方案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<T>
时,可以使用Enumerable.ToDictionary转换为Dictionary<string, string>
。
来自列表
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<T>
)
当数据来自DataTable
时,您使用dt.Rows
进行迭代并添加到Dictionary<string, string>
。
来自
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, '')
【讨论】:
以上是关于将表转换为像字典一样的 json 对象 SQL?的主要内容,如果未能解决你的问题,请参考以下文章