Automapper: Mapping objects Part 3 of 7 (Nested Mapping)

Posted in .NET, Automapper on March 9th, 2011 by taswar

In this part we will use the same OrderDto Object that we had previously but we will let Automapper to map the inner objects.

Once again here is the Domain Objects First

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Order 
public class Order
    {
        public string OrderNo { get; set; }
        public Customer Customer { get; set;  }
        public DateTime PurchaseDate { get; set; }
        public IEnumerable<OrderItems> LineItems { get; set; }
        public bool ShipToHomeAddress { get; set; }
        public decimal GetTotal()
        {
            return LineItems == null ? 0 : LineItems.Sum(x => x.GetTotalPrice());
        }
        public Guid InternalId { get; set; }
    }
 
//OrderItems
public class OrderItems
    {
        public decimal Price { get; set; }
        public string Name { get; set; }
        public int Quantity { get; set; }
        public decimal GetTotalPrice()
        {
            return Price * Quantity;
        }
    }

The Dto (Data Transfer Object) look like

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
public class OrderDto
    {
        public string CustomerName { get; set; }
        public decimal Total { get; set; }
        public string OrderNumber { get; set; }
        public IEnumerable<OrderItemsDto> LineItems { get; set; }
    }
 
//OrderItemsDto
public class OrderItemsDto
    {
        public string Name { get; set; }
        public int Quantity { get; set; }
        public decimal Price { get; set; }
    }

This time when we map Order to OrderDto we will also provide the mapping of OrderItems to OrderItemsDto.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public ActionResult OrderItems()
        {
            var orders = _respository.GetAll();
 
            Mapper.CreateMap<Order, OrderDto>()
                .ForMember(dest => dest.OrderNumber, opt => opt.MapFrom(src => src.OrderNo));
 
            Mapper.CreateMap<OrderItems, OrderItemsDto>();
 
            var model = Mapper.Map<IEnumerable<Order>, IEnumerable<OrderDto>>(orders);
 
            return View(model);
        }
//View
<table>
    <tr>
        <th>Order Number</th>
        <th>Name</th>
        <th>Total</th>
        <th>Items</th>
    </tr>
@foreach (var item in Model)
{
    <tr>
        <td>@item.OrderNumber</td>
        <td>@item.CustomerName</td>
        <td>$@item.Total</td>
        <td>            
            @foreach (var child in item.LineItems)
            {
                @string.Format("({0}) {1} - ${2}", @child.Quantity, @child.Name, @child.Price)<br />
            }           
       </td>
    </tr>
}
 
</table>

As you can see I have taught automapper about its inner child/object mapping before calling Map, thus it knows about the inner mapping, our result would show like

In the next part I will be showing projection in Automapper.

Previous Post:
Part 1 NullSubsitution
Part 2 Flattening by Convention

Share

4 Responses

  1. bdaniel7 Says:

    Have you used an sql profiler to see the queries sent to the database? The code might look clean but might hide some unoptimized sql queries, that will not be good on production.

  2. taswar Says:

    Valid point but in my demo I am not using sql, my repository is just a bunch of objects that are manually created. I do use sqlserver in another project and have not found a big performance issue since we have a dba who is optimizing all the time, and in my last part of this series I will be showing some tips on performance with Automapper.

  3. Alex Says:

    Mapper.CreateMap()
    .ForMember(dest => dest.OrderNumber, opt => opt.MapFrom(src => src.OrderNo));

    How I can map property from nullable nested object?
    In situation when orderItem.Order == null a had Object reference not set to an instance of an object exception.

  4. taswar Says:

    One can use the NullSubsitute in my first posting I showed how to use a NullSubsitute of it. Or you could consider Ignore so that it doesnt map.
    http://taswar.zeytinsoft.com/2011/03/07/automapper-mapping-objects-part-1-of-7-nullsubsitution/

Leave a Comment