Dapper - 如何映射复杂对象

问题描述 投票:0回答:1

我的目标是:

public class ApplePrice
{
    public DateTime Date { get; set; }
    public Dictionary<int, double> HourlyPrice { get; set; }
}

我的数据库包含每个日期的许多价格,我需要返回

ApplePrice
对象的列表。我的查询是

SELECT * FROM Prices WHERE Date > getdate()-7
SELECT * FROM Prices WHERE Date = {Date}

如何使用 Dapper 从这些查询中映射对象?

c# sql-server .net-core dapper
1个回答
2
投票

Dapper 文档

Query
QueryAsync
返回可枚举的动态类型(对于
QueryAsync
是异步的)。

可以在内存端进行映射。使用 System.Linq

Date
分组并通过
Dictionary<int, double>
.
 将分组数据集转换为 
.ToDictionary()

using System.Linq;

using (var connection = new SqlConnection(connectionString))
{
    var sql = "SELECT * FROM Prices WHERE Date > getdate()-7";
    var result = (await connection.QueryAsync(sql))
        .GroupBy(x => x.Date)
        .Select(x => new ApplePrice
        {
            Date = x.Key,
            HourlyPrice = x.ToDictionary(k => k.Hour, v => v.Price)
        })
        .ToList();
}

根据您的 DBMS 和版本,有些 DBMS 允许您构造包含 JSON 对象的结果。例如:

通过 PostgreSQL(从版本 11 开始)

SELECT Date,
    json_agg(json_build_object(
        Hour::numeric, Price::money
    ))  AS HourlyPrice
FROM Prices 
WHERE Date > getdate()-7
GROUP BY Date

通过 MySQL(从 5.7 版开始)

SELECT Date,
    GROUP_CONCAT(JSON_OBJECT(
        Hour, Price
    )) AS HourlyPrice
FROM Prices 
WHERE Date > getdate()-7
GROUP BY Date

通过 SQL Server 2016 (13.x)

SELECT Date,
       JSON_QUERY(CONCAT('[', STRING_AGG(CONCAT('{"', Hour, '":', Price, '}'), ','), ']')) AS HourlyPrice
FROM Prices 
WHERE Date > DATEADD(day, -7, GETDATE())
GROUP BY Date

通过上述查询(基于您的 DBMS 和版本),您可以映射到

List<ApplePrice>
.

using System.Linq;

using (var connection = new SqlConnection(connectionString))
{
    var sql = "<Replace with Query>";

    var result = (await connection.QueryAsync(sql))
        .Select(x => new ApplePrice
        {
            Date = x.Date
            HourlyPrice = x.HourlyPrice.ToDictionary(k => Convert.ToInt32(k.Key), v => Convert.ToDouble(v.Value))
        })
        .ToList();
}
© www.soinside.com 2019 - 2024. All rights reserved.