Jack
Jack

Reputation: 117

Automapper with Join query

I'm working on .Net core 3 web API with AutoMapper

I have a customer entity and order entity. I have created DTO for each like below

 public partial class Customer
    {

        public int CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public virtual ICollection<Order> Orders { get; set; }
    }

  public class CustomerDto
    {
        public int CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

   public partial class Order
    {
        public int OrderId { get; set; }
        public int? CustomerId { get; set; }
        public byte OrderStatus { get; set; }

        public virtual Customer Customer { get; set; }
        public virtual Staff Staff { get; set; }
        public virtual Store Store { get; set; }
        public virtual ICollection<OrderItem> OrderItems { get; set; }
    }
}

public class OrderDto
{
    public int OrderId { get; set; }
    public int? CustomerId { get; set; }
    public byte OrderStatus { get; set; }
}

Now in the CustomerRepository I have a function that returns customer data and used in Customer controller like below

   public async Task<IActionResult> GetCustomers ()
        {
            var result = await _repo.GetCustomers();
            
            return Ok(_mapper.Map<List<CustomerDto>>(result));
        }

Everything is working fine till now. I wanted to add a function in customer repository to return customer data along with list of his/her orders

I tried that by adding a List in CustomerDto as below but that made another issue for me

   public class CustomerDto
    {
        public int CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<OrderDto> Orders { get; set; }
    }

By doing that now when I call the action GetCustomers it returns in json an empty List<OrderDto> which makes sense. But I don't want that. I just want to return the customer data.

But for the new function I want to return Customer data and list of orders. Now how to do such thing?

I don't think we should create different DTO for different SQL join query we make. So what it is the approach here?

Upvotes: 0

Views: 749

Answers (1)

Nihat &#199;elik
Nihat &#199;elik

Reputation: 11

I have a similar example.

You should use the AutoMapper ProjectTo method with Include method.

My main dto.

public class VariantViewDto : BaseDto, IDto
{
    public int Id { get; set; }
    public string VariantName { get; set; }
    public bool IsActive { get; set; }
    public List<VariantValueViewDto> VariantValues { get; set; }
}

My child dto

public class VariantValueViewDto : IDto
{
    public int Id { get; set; }
    public int VariantId { get; set; }
    public string VariantName { get; set; }
    public string Value { get; set; }
}

Auto Mapper Include.

var query = _variantRepository.GetQuery(); //It should be IQueryable
query = query.Include(u => u.CreateUser);
query = query.Include(u => u.UpdateUser);
query = query.Include(u => u.VariantValues);
var variantsViewDto = await _mapper.ProjectTo<VariantViewDto>(query).ToListAsync();
return new SuccessDataResult<IEnumerable<VariantViewDto>>(variantsViewDto);

And result

    {
        "id": 1,
        "variantName": "Renk",
        "isActive": true,
        "variantValues": [
            {
                "id": 2,
                "variantId": 1,
                "variantName": "Renk",
                "value": "Sarı"
            },
            {
                "id": 3,
                "variantId": 1,
                "variantName": "Renk",
                "value": "Kırmızı"
            }
        ],
        "createDate": "2021-06-21T16:44:11.451633",
        "updateDate": null,
        "createUserId": 37,
        "createUserName": "string",
        "updateUserId": null,
        "updateUserName": ""
    },

Upvotes: 1

Related Questions