将 Dapper 原始 SQL 结果转换为嵌套 JSON 数组

Convert Dapper raw SQL Result to Nested JSON Array

我在 .Net Core 5 中开发了一个网络 api,它使用 dapper 来 运行 一个 tabled 值函数和 return SQL结果。这些结果然后用于填充 VueJS 前端的各种 select 框。然而,当我开始构建我的前端更多时,我意识到我的 JSON 数组可以嵌套以真正帮助减少我对服务器发出的请求数量,因为我的 select 框是依赖的。例如,一个 select 框包含州,然后下一个 select 框与这些州的城市相关。通过在数据库中的州 table 和城市 table 之间添加一个内部连接,将 tabled 值函数调整为 return 单个 table 很容易。连接键是一个名为 STATE_ID 的字段。因此,由于每个州有多个城市,我只有多行。所以现在我想弄清楚的是如何在我的网络 api 和我的 table 值函数结果中获取这个结果,而不使用模型到嵌套的 json 数组中,这样我的结果如下:

[{state: 'Maryland', cities :[{city: 'Baltimore'}, {city: 'Harford County'}]} , 
{state: 'Pennsylvania', cities :[{city: 'York'}, {city: 'Fawn Grove'}]}]

Table 值函数结果来自 A2Q00001_StateInfo(USERNUMBER):

|      State_ID       |     State_Name   |      City_Name      |  
|---------------------|------------------|---------------------|
|          1          |      Maryland    |    Baltimore        |
|          1          |      Maryland    | Harford County      |
|          2          |  Pennsylvania    |    York             |
|          2          |  Pennsylvania    | Fawn Grove          |

我的控制器如下:

        public ActionResult StateAndCities([FromQuery] String USERNUMBER)
        {
 
            //We have parameters here just in case we want to use them
            IEnumerable queryResult;
            String query = "select * from dbo.A2Q00001_StateInfo(@USERNUMBER);";

            using (var connection = new SqlConnection(connectionString))
            {
                queryResult = connection.Query(query, new { USERNUMBER = USERNUMBER });
            }

            return Ok(queryResult);

        }

我在网上看到的所有教程都使用模型来创建嵌套的 JSON 对象和 return 但是我不确定如何使用 Ok( ) 在 asp.net 核心中发挥作用。这甚至是可能的,还是我需要对来自 dapper 查询的 queryResult 执行操作?任何一点在正确的方向上都会很棒。

我的建议:将其分成几个步骤。我猜你的 A2Q00001_StateInfo UDF 在这里 returns 一个 StateCity 列(编辑:我很接近,它是 State_Name,通过编辑),除其他事项外。所以第一步:让我们读一下:

class SomeType
{
    public string State_Name { get; set; }
    public string City { get; set; }
}
//...
var queryResult = connection.Query<SomeType>(
    "select State_Name, City from dbo.A2Q00001_StateInfo(@USERNUMBER);",
    new { USERNUMBER }).AsList();

这会将我们的数据从数据库中获取到本地内存中。请注意,我过滤掉了不相关的列以减少开销。

现在,下一步 是构建数据的结构 - 看起来您想按州聚合,并在每个州创建一个城市数组;所以:让我们这样做:

var structured =
    from grp in queryResult.GroupBy(x => x.State_Name)
    select new
    {
        state = grp.Key,
        cities = grp.Select(row => new { city = row.City }).ToArray()
    };

这为我们提供了一个投影(使用匿名类型)来进行我们想要的重组。最后,我们需要将其转换为JSON;这 可能 很简单:

return Ok(structured);

或者您可能需要直接使用 Json/JsonResult API。但是,既然数据是结构化的:任何 JSON 序列化程序都应该知道我们想在这里做什么。


注意:您可能可以将所有这些重写成一个表达式,但是:不要那样做;你不是想给编译器留下深刻印象——它不会关心任何一种方式。让下一个需要接触它的人(很可能就是你)的代码清晰明了。