Search code examples
c#automapperdto

AutoMapper avoid nested loops


I am currently using Automapper to map from my domain model to DTO. Inside my Domain model I have 3 bool properties (IsHomeowner, IsTenant, IsLivingWithParents) which are used to set the value of a property inside the ViewModel i.e. PersonDTO called LivingStatus

However, to get to my end result I am having to loop through the Person model, create Dictionary to store my values and then using AfterMap create a nested loop and set the value inside there.

Although it works but is not an ideal solution because it is more likely to create memory leaks as data increases in Size.

So was wondering if there is anything in AutoMapper to avoid this?

Here is my code

View Model

public class PersonDTO{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string Surname { get; set; }
  public Status LivingStatus { get; set; }
}

Domain Model

public class Person{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string Surname { get; set; }
   public bool IsHomeOwner { get; set; }
   public bool IsTenant { get; set; }
   public bool IsLivingWithParents { get; set; }
}

public enum Status{
   Homeowner=1,
   Tenant=2,
   LivingWithParents=3
}
public List<PersonDTO> GetEmployee(List<Person> persons)
{
   var livingStatus = new Dictionary<int, Status>();
   foreach (var person in persons)
   {
       if (person.IsHomeOwner)
       {
          livingStatus.Add(person.Id, Status.Homeowner);
       }
       else if (person.IsTenant)
       {
          livingStatus.Add(person.Id, Status.Tenant);
       }
       else
       {
          livingStatus.Add(person.Id, Status.LivingWithParents);
       }
   }

   return _mapper.Map<List<Person>, List<PersonDTO>>(persons, opts => opts.AfterMap((src, dest) { 
   foreach(var person in dest)
   {
     person.LivingStatus = livingStatus.Single(x => x.Key == person.Id).Value;
   }
   }));
}

Solution

  • Finally found a better solution by creating a Method which handles the conversion and then using it in the mapping configuration :)

    private Status TypeConverter(Person person)
    {
        if (person.IsHomeOwner)
        {
          return Status.Homeowner;
        }
        else if (person.IsTenant)
        {
          return Status.Tenant;
        }
        else
        {
          return Status.LivingWithParents;
        }
    
        return person.Status;
    }
    

    Mapping configuration

    CreateMap<Person, PersonDTO>()
                    .ForMember(dest => dest.LivingStatus, opt => opt.MapFrom(src => TypeConverter(src)));