'How to use Automapper to project object to Dto in LINQ

I am working on .NET Core 6 along with EF Core. I want to convert Customer and Order object that I have inside LINQ select to CustomerDto and OrderDto using ProjectTo.

Using libraries

using AutoMapper;
using AutoMapper.QueryableExtensions;

I am aware how to map IQueryable using the code shown here:

var x = (from customer in db.Customers
         where customer.CustomerId == CustomerId
         select customer).ProjectTo<CustomerDto>(_mapper.ConfigurationProvider);

but I'm not sure how to project inside new or if it should be done differently? Below is LINQ code that I want customer to CustomerDto & Order to OrderDto

var customerOrdersQuery =
            (from customer in db.Customers.Where(x => x.CustomerId == CustomerId)
             join orders in db.Orders on customer.CustomerId equals orders.CustomerId into cst_Ord
             from customerOrders in cst_Ord.DefaultIfEmpty()
             select new { 
                 customer,        //ProjectTo<CustomerDto>
                 customerOrders   //ProjectTo<OrderDto>
             }).AsEnumerable();


Solution 1:[1]

Afaik you need an intermediary class CustomerWithOrdersSource which you map to CustomerWithOrdersDto, using Automapper's ProjectTo.

Mapping

public class CustomerWithOrdersSource
{
   public Customer Customer {get;set;}
   public ICollection<Order> Orders {get;set;}
}
public class CustomerWithOrdersDto
{
   public CustomerDto Customer {get;set;}
   public ICollection<OrderDto> Orders {get;set;}
}
CreateMap<CustomerWithOrdersSource, CustomerWithOrdersDto>();

Query

var customerOrdersQuery =
            (from customer in db.Customers.Where(x => x.CustomerId == CustomerId)
             join orders in db.Orders on customer.CustomerId equals orders.CustomerId into cst_Ord
             from customerOrders in cst_Ord.DefaultIfEmpty()
             select new CustomerWithOrdersSource() { 
                 Customer = customer,
                 Orders = customerOrders
             }).ProjectTo<CustomerWithOrdersDto>(_mapper.ConfigurationProvider);

Edit: According to @Lucian Bargaoanu you can project directly from anonymous object as well. But this way you could easily customize the mapping by editing the mapping profile, if necessary later on.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1