简洁的行到 json

Posted

技术标签:

【中文标题】简洁的行到 json【英文标题】:Dapper row to json 【发布时间】:2019-04-10 08:04:49 【问题描述】:

问题

作为 Dapper Query 的结果,我们有一个 Dapper Row,我想将它作为 json 字符串存储在我们的数据库中。不幸的是,我似乎无法让它发挥作用。 那么,让我们从一些背景信息开始吧。

背景信息

我们正在做一个项目,我们从表中提取表名称,以了解我们必须处理哪些表。我们还希望它尽可能灵活,因此我们决定不对我们的数据使用特定的 POCO。

我们使用的是 SQL Server 2014,所以很遗憾我们还没有“FOR JSON”选项。

代码

我们的代码看起来像这样,其中 GetData 是我们的实际查询:

var data = _queryHandler.Handle(new GetData(tableName.ToString(), 0), database);

从技术上讲,句柄只是连接到数据库,调用

conn.QueryAsync(query, parameters)

GetData 看起来像这样(简化):

EXEC ('SELECT * FROM ' + @table + ')'

推理

因为表名每次都不同,我们不想在输出上强制使用 POCO。有时它是一个用户,有时是一个角色,可以这么说,所以无法预测它返回什么输出。

结果

这很好用。我们可以提取变量中的数据,这看起来像是一个 IEnumerable,应该没问题。我想我们可以循环读取它们并提取行。到目前为止,没问题。

手头的问题

接下来我们要做的是将数据从所述 DapperRow 转换为 json 字符串,但我似乎无法让数据表现得像 json 字符串,因为 JsonConvert.SerializeObject 惨遭失败。 DapperRow 看起来像这样(再次简化)。

DapperRow, Id = '07501399-b385-4d8e-bacc-gad9d04c35f7', UserName = 'test8', ApplicationId = '4721fafb-12e6-4e3c-9298-etd82d18a0cb', IsApproved = 'True', IsLockedOut = 'False', CreateDate = '26-3-2019 07:52:55' 

我已经研究过SqlMapper.ITypeHandler 之类的东西,但我仍然没有到达那里。例如,对于 TypeHandler,我卡在了 destinationType 上,因为我不想要一个特定的类型——好吧,除了 json 对象。但这不是公认的类型。

public class JsonObjectTypeHandler : SqlMapper.ITypeHandler

    public void SetValue(IDbDataParameter parameter, object value)
    
        parameter.Value = (value == null)
            ? (object)DBNull.Value
            : JsonConvert.SerializeObject(value);
        parameter.DbType = DbType.String;
    

    public object Parse(Type destinationType, object value)
    
        return JsonConvert.DeserializeObject(value.ToString(), destinationType);
    

我想到的唯一另一件事是提取每一列并从中构建一个类型对象,但正如我所说,我们不想像我们想要的那样对数据使用模型/类型保持灵活。

谁能指出我正确的方向?我觉得我似乎忽略了一些简单的事情。

【问题讨论】:

你不能使用JsonConvert.SerializeObject(result)吗? 【参考方案1】:

如果您使用非类型化的Query API,则每个返回的行也是一个IDictionary<string,object>(除了dynamic API),通常与JsonConvert 配合使用可以正常工作;例如,以下对我来说可以:

var tables = (from row in await conn.QueryAsync("select top 5 * from sys.tables")
              select (IDictionary<string, object>)row).AsList();
var json = JsonConvert.SerializeObject(tables, Formatting.Indented);
System.Console.WriteLine(json);

输出:

[
  
    "name": "spt_fallback_db",
    "object_id": 117575457,
    "principal_id": null,
    "schema_id": 1,
    "parent_object_id": 0,
    "type": "U ",
    "type_desc": "USER_TABLE",
    "create_date": "2003-04-08T09:18:01.557",
    "modify_date": "2017-08-22T19:40:40.763",
    "is_ms_shipped": true,
    "is_published": false,
    "is_schema_published": false,
    "lob_data_space_id": 0,
    "filestream_data_space_id": null,
    "max_column_id_used": 8,
  ... etc

【讨论】:

您的查询输出与我的输出完全相同,所以这不是问题。显然,我必须做的唯一更改是将 AsList() 添加到查询中以使其正常工作。所以我是对的,这很简单 - 感谢您帮助我解决这个问题!

以上是关于简洁的行到 json的主要内容,如果未能解决你的问题,请参考以下文章

比Newtonsoft.Json轻量快速简洁的实体JSON转换库YeaJur.Mapper

最简单简洁高效的Json数据解析

以简洁的方式显示从 Flask 返回的 JSON

有没有更简洁的方式来在 TypeScript 中表示这个 JSON 对象?

使用JSON提供测验的简洁方法

在多个文件中写同一行的简洁方法 - Python