简体   繁体   中英

How to reverse map to an existing parent object using AutoMapper?

Consider the following classes:

public class Customer
{
    public Guid Id { get; set; }
    public List<Address> Addresses { get; set; }
    public List<Order> Orders { get; set; }
}

public class Address
{
    public Guid Id { get; set; }
    public Customer Customer { get; set; }    // parent
    // ...
}

public class Order
{
    public Guid Id { get; set; }
    public Customer Customer { get; set; }    // parent
    public Address Address { get; set; }
    // ...
}

And the data transfer objects (DTOs):

public class CustomerDto
{
    public Guid Id { get; set; }
    public AddressDto[] Addresses { get; set; }
    public OrderDto[] Orders { get; set; }
}

public class AddressDto
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    // ...
}

public class OrderDto
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    public Guid AddressId { get; set; }
}

Mapping (and flattening) from Customer to CustomerDto is easy. However, I'm having trouble reverse mapping from CustomerDto to Customer .

AutoMapper is not able to figure out the Customer property in Address or Order . It also can't figure out the Address property in Order .

I can make it work by first "ignoring" these properties by using the Ignore configuration method, and then using AfterMap to manually find the objects and assign them appropriately.

Is there a way for AutoMapper to do this automatically?

I think what you are looking for is .ReverseMap() - http://docs.automapper.org/en/stable/Reverse-Mapping-and-Unflattening.html

So given the following mappings:

        var mapper = new MapperConfiguration(expression =>
        {
            expression.CreateMap<Customer, CustomerDto>()
                .ForMember(dto => dto.Id, obj => obj.MapFrom(customer => customer.Id))
                .ReverseMap();
            expression.CreateMap<Address, AddressDto>()
                .ForMember(dto => dto.Id, obj => obj.MapFrom(address => address.Id))
                .ForMember(dto => dto.CustomerId, obj => obj.MapFrom(address => address.Customer.Id))
                .ReverseMap();
            expression.CreateMap<Order, OrderDto>()
                .ForMember(dto => dto.Id, obj => obj.MapFrom(order => order.Id))
                .ForMember(dto => dto.AddressId, obj => obj.MapFrom(order => order.Address.Id))
                .ForMember(dto => dto.CustomerId, obj => obj.MapFrom(order => order.Customer.Id))
                .ReverseMap();
        }).CreateMapper();

And object:

        var customerTest = new Customer
        {
            Id = Guid.NewGuid(),
            Addresses = new List<Address>
            {
                new Address
                {
                    Id = Guid.NewGuid(),
                    Customer = new Customer{ Id = Guid.NewGuid() }
                }
            },
            Orders = new List<Order>
            {
                new Order
                {
                    Id = Guid.NewGuid(),
                    Customer = new Customer{ Id = Guid.NewGuid() },
                    Address = new Address{ Id = Guid.NewGuid() }
                }
            }
        };

You could do the following:

        var resultDto = mapper.Map<CustomerDto>(customerTest);
        var resultModel = mapper.Map<Customer>(resultDto);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM