У меня 2 класса, порядок и адрес:

public class Order
{
    public string OrderId { get; set; }
    public Address ShippingAddress { get; set; }
    public Address BillingAddress { get; set; }
}

А также

public class Address
{
    public string Street { get; set; }
    public string Town { get; set; }
    public string Zip { get; set; }
}

База данных хранит заказы и адреса в одной таблице, например:

CREATE TABLE Orders
    (
        OrderId NVARCHAR(56) PRIMARY KEY,
        BillingStreet NVARCHAR(256),
        BillingTown NVARCHAR(256),
        BillingZip NVARCHAR(256),
        ShippingStreet NVARCHAR(256),
        ShippingTown NVARCHAR(256),
        ShippingZip NVARCHAR(256)
    )

enter image description here

Как я могу заставить dapper сопоставить это с классом Order?

2
Eli Perl 23 Дек 2015 в 14:36

2 ответа

Лучший ответ

Вот как вы можете сделать это, сделав запрос обобщающим столбцы биллинга и доставки и используя версию Query, которая принимает несколько типов и сообщает ему о разделении, когда он видит столбец с именем «Адрес». Затем вы просто назначаете объекты Address соответствующему свойству объекта Order.

connection.Query<Order, Address, Address, Order>(
    @"SELECT OrderId, 
             BillingAddress As Address, 
             BillingTown As Town, 
             BillingZip As Zip, 
             ShippingAddress As Address, 
             ShippingTown As Town, 
             ShippingZip As Zip,  
      FROM Orders",
    (o, ba, sa) =>
    {
        o.BillingAddress = ba;
        o.ShippingAddress = sa;
        return o;
    },
    splitOn: "Address");
3
juharr 23 Фев 2016 в 16:11

Я не думаю, что это возможно с Dapper, поскольку он обрабатывает строку как единый объект. Было бы возможно, если бы вы изменили структуру своей таблицы:

CREATE TABLE Orders
(
    OrderId NVARCHAR(56) PRIMARY KEY,
    BillingAddressId INT
    ShippingAddressId INT
)

Тогда вам придется изменить свой класс на:

public class Order
{
    public string OrderId { get; set; }
    public int ShippingAddressId {get; set;}
    public virtual Address ShippingAddress { get; set; }
    public int BillingAddressId {get; set;}
    public virtual Address BillingAddress { get; set; }
}

И просто используйте мульти-маппинг.

Другой вариант - использовать расширения Dapper, например, Dapper-FluentMap или Dapper Extensions, которые помогут сопоставить столбцы с классами.

0
kamil-mrzyglod 23 Дек 2015 в 12:22