【问题标题】:Mapping multiple complex type properties with Dapper使用 Dapper 映射多个复杂类型属性
【发布时间】:2019-01-30 08:30:20
【问题描述】:

我有以下 Dapper 查询:

var orderModels = db.Query<OrderModel>(@"
SELECT
    o.[Id],
    o.[CustomerId],

    o.[DeliveryAddress_FirstName],
    o.[DeliveryAddress_LastName],
    o.[DeliveryAddress_Line1],
    o.[DeliveryAddress_Line2],
    o.[DeliveryAddress_City],
    o.[DeliveryAddress_State],
    o.[DeliveryAddress_PostCode],
    o.[DeliveryAddress_Country],

    o.[BillingAddress_FirstName],
    o.[BillingAddress_LastName],
    o.[BillingAddress_Line1],
    o.[BillingAddress_Line2],
    o.[BillingAddress_City],
    o.[BillingAddress_State],
    o.[BillingAddress_PostCode],
    o.[BillingAddress_Country]
FROM
    [Order] o
");

我想将它加载到以下结构的数据模型中:

public class OrderModel
{
    public int Id { get; set; }
    public int CustomerId { get; set; }

    public AddressModel DeliveryAddress { get; set; }
    public AddressModel BillingAddress { get; set; }
}

public class AddressModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostCode { get; set; }
    public string Country { get; set; }
}

我已尝试查找此内容,并且有一个 feature in Dapper called multi-mapping。但是,当我不加入来自多个表的结果时,我无法弄清楚如何在我的用例中使用它。

对于像 Dapper 这样的 ORM 来说,这感觉是一个非常常见的场景,所以我确定我只是遗漏了一些明显的东西。如果您更了解 Dapper,请提供帮助。

最好的方法是什么?

【问题讨论】:

    标签: c# .net orm dapper


    【解决方案1】:

    Dapper 不关心连接,您只需为 splitOn 选项提供正确的字段,例如:

        var orderModels = db.Query<OrderModel, AddressModel, AddressModel, OrderModel>(@"
        SELECT
            o.[Id],
            o.[CustomerId],
    
            o.[DeliveryAddress_FirstName] AS [FirstName], // Field names should match properties of your model
            o.[DeliveryAddress_LastName] AS [LastName],
            o.[DeliveryAddress_Line1] AS [Line1],
            o.[DeliveryAddress_Line2] AS [Line2],
            o.[DeliveryAddress_City] AS [City],
            o.[DeliveryAddress_State] AS [State],
            o.[DeliveryAddress_PostCode] AS [PostCode],
            o.[DeliveryAddress_Country] AS [Country],
    
            o.[BillingAddress_FirstName] AS [FirstName],
            o.[BillingAddress_LastName] AS [LastName],
            o.[BillingAddress_Line1] AS [Line1],
            o.[BillingAddress_Line2] AS [Line2],
            o.[BillingAddress_City] AS [City],
            o.[BillingAddress_State] AS [State],
            o.[BillingAddress_PostCode] AS [PostCode],
            o.[BillingAddress_Country] AS [Country]
        FROM
            [Order] o
        ", 
    (order, deliveryAddress,  billingAddress) => {
       order.DeliveryAddress = deliveryAddress; 
       order.BillingAddress = billingAddress; 
       return order; 
    },
    splitOn: "FirstName,FirstName");
    

    this article中有解释。

    此外,选择的字段名称必须与模型属性名称匹配,以便 Dapper 自动找出映射。

    【讨论】:

    • 感谢您的帮助。我认为您的类型参数错误,应该是&lt;OrderModel, AddressModel, AddressModel, OrderModel&gt;。但即使我这样做了,帐单地址和送货地址的所有属性仍然为 NULL。
    • yup 修复了参数顺序...将再看看它
    • 我认为问题可能是这些列仍然以DeliveryAddress_ 为前缀...我尝试为这些列添加别名以删除前缀并且它起作用了。但我不得不说,必须重命名所有这些列(并且有多个具有相同名称的列)感觉有点奇怪。我真的不喜欢只为 Dapper 做一个特殊的投影。如果可以配置 Dapper 会更好,因为映射结果是 Dapper 关心的问题,它不应该让我改变我的查询。如果这些是在存储过程中生成的结果怎么办?
    • 你可以看custom column mappings 但我自己没试过
    • 谢谢,我认为自定义映射在这种情况下不会有帮助,但值得一试。无论如何,使用列别名的解决方案是有效的,即使它并不完美。
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2015-04-13
    • 1970-01-01
    相关资源
    最近更新 更多