Dapper 行到 json

Gam*_*bit 5 .net c# json dapper

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

背景资料

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

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

代码

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

var data = _queryHandler.Handle(new GetData(tableName.ToString(), 0), database);
Run Code Online (Sandbox Code Playgroud)

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

conn.QueryAsync(query, parameters)
Run Code Online (Sandbox Code Playgroud)

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

EXEC ('SELECT * FROM ' + @table + ')'
Run Code Online (Sandbox Code Playgroud)

推理

由于表名每次都不同,我们不想在输出上强制执行 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' }}
Run Code Online (Sandbox Code Playgroud)

我已经研究过类似的东西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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我唯一想到的另一件事是提取每一列并从中构建一个类型对象,但正如我所说,我们不想为数据使用模型/类型,因为我们希望保持它的灵活性.

有人能指出我正确的方向吗?我有一种感觉,我似乎忽略了一些简单的事情。

Mar*_*ell 8

如果您使用的是非类型化QueryAPI,则每个返回的行也是一个IDictionary<string,object>(除了dynamicAPI 之外),通常与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);
Run Code Online (Sandbox Code Playgroud)

输出:

[
  {
    "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
Run Code Online (Sandbox Code Playgroud)