AutoMapper Complex Mapping in C#

AutoMapper Complex Mapping in C# with Examples

In this article, I am going to discuss the AutoMapper Complex Mapping in C# with some examples. Please read our previous article before proceeding to this article where we discussed the basics of Automapper in C# with examples. When both the type involved in the mapping contains properties of the complex type then in such scenarios we need to use the AutoMapper Complex Mapping in C#.

Let us understand AutoMapper Complex Mapping in C# with an example. We are going to use the following four classes for this demo.

AutoMapper Complex Mapping in C#

Business Requirement:

Our requirement is to map the Employee object to EmployeeDTO object. To make this demo simple, here we created both the classes with the same property names. But the thing that we need to keep in mind is here we created the address property as a complex type. Then we are creating a static method where we need to write the mapping code. The following is the code to Initialize the Mapper.

AutoMapper Complex Mapping in C#

Below is the complete code.

using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Call the InitializeAutomapper method to initialize the Mapper
            //In InitializeAutomapper method we defined the Mappings
            InitializeAutomapper();

            //Step2: Create and populate the Employee object
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee();
            emp.Name = "James";
            emp.Salary = 20000;
            emp.Department = "IT";
            emp.address = empAddres;
            
            //Step3: Use the mapper to map the employee data with the Employee DTO
            var empDTO = Mapper.Map<Employee, EmployeeDTO>(emp);
            
            Console.WriteLine("Name:" + empDTO.Name + ", Salary:" + empDTO.Salary +", Department:" + empDTO.Department);
            Console.WriteLine("City:" + empDTO.address.City + ", State:" + empDTO.address.Stae + ", Country:" + empDTO.address.Country);
            Console.ReadLine();
        }

        static void InitializeAutomapper()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Employee, EmployeeDTO>();
            });
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public int Salary { get; set; }
        public string Department { get; set; }
        public Address address { get; set; }
    }

    public class EmployeeDTO
    {
        public string Name { get; set; }
        public int Salary { get; set; }            
        public string Department { get; set; }
        public AddressDTO address { get; set; }
    }


    public class Address
    {
        public string City { get; set; }
        public string Stae { get; set; }
        public string Country { get; set; }
    }


    public class AddressDTO
    {
        public string City { get; set; }
        public string Stae { get; set; }
        public string Country { get; set; }
    }
}

Now, run the application and you will see the output as expected as shown below.

AutoMapper with Nested Types

Let’s change the complex property address to addressDTO of the EmployeeDTO class as shown below.

AutoMapper with Nested Types

Below is the complete code.
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Call the InitializeAutomapper method to initialize the Mapper
            //In InitializeAutomapper method we defined the Mappings
            InitializeAutomapper();

            //Step2: Create and populate the Employee object
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee();
            emp.Name = "James";
            emp.Salary = 20000;
            emp.Department = "IT";
            emp.address = empAddres;
            
            //Step3: Use the mapper to map the employee data with the Employee DTO
            var empDTO = Mapper.Map<Employee, EmployeeDTO>(emp);
            
            Console.WriteLine("Name:" + empDTO.Name + ", Salary:" + empDTO.Salary +", Department:" + empDTO.Department);
            Console.WriteLine("City:" + empDTO.addressDTO.City + ", State:" + empDTO.addressDTO.Stae + ", Country:" + empDTO.addressDTO.Country);
            Console.ReadLine();
        }

        static void InitializeAutomapper()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Employee, EmployeeDTO>();
            });
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public int Salary { get; set; }
        public string Department { get; set; }
        public Address address { get; set; }
    }

    public class EmployeeDTO
    {
        public string Name { get; set; }
        public int Salary { get; set; }            
        public string Department { get; set; }
        public AddressDTO addressDTO { get; set; }
    }


    public class Address
    {
        public string City { get; set; }
        public string Stae { get; set; }
        public string Country { get; set; }
    }


    public class AddressDTO
    {
        public string City { get; set; }
        public string Stae { get; set; }
        public string Country { get; set; }
    }
}

Now run the application. It will give you the below error

AutoMapper with Nested Types

This is because the property name for addressDTO is not found in the Employee object. So we get the null reference error. To solve the above issue we need to map the address property to addressDTO property as shown below.

AutoMapper with Nested Types

Now run the application and it will give you the results as expected.

Let’s modify the property name in the AddressDTO class as shown below.

AutoMapper with Nested Types

Below is the complete example.
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Call the InitializeAutomapper method to initialize the Mapper
            //In InitializeAutomapper method we defined the Mappings
            InitializeAutomapper();

            //Step2: Create and populate the Employee object
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee();
            emp.Name = "James";
            emp.Salary = 20000;
            emp.Department = "IT";
            emp.address = empAddres;
            
            //Step3: Use the mapper to map the employee data with the Employee DTO
            var empDTO = Mapper.Map<Employee, EmployeeDTO>(emp);
            
            Console.WriteLine("Name:" + empDTO.Name + ", Salary:" + empDTO.Salary +", Department:" + empDTO.Department);
            Console.WriteLine("City:" + empDTO.addressDTO.EmpCity + ", State:" + empDTO.addressDTO.EmpStae + ", Country:" + empDTO.addressDTO.Country);
            Console.ReadLine();
        }

        static void InitializeAutomapper()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Employee, EmployeeDTO>()
                .ForMember(dest => dest.addressDTO, act => act.MapFrom(src => src.address));
            });
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public int Salary { get; set; }
        public string Department { get; set; }
        public Address address { get; set; }
    }

    public class EmployeeDTO
    {
        public string Name { get; set; }
        public int Salary { get; set; }            
        public string Department { get; set; }
        public AddressDTO addressDTO { get; set; }
    }
    
    public class Address
    {
        public string City { get; set; }
        public string Stae { get; set; }
        public string Country { get; set; }
    }
    
    public class AddressDTO
    {
        public string EmpCity { get; set; }
        public string EmpStae { get; set; }
        public string Country { get; set; }
    }
}

Now run the application. It will give you the below error.

AutoMapper with Nested Types in C#

So when the complex type property names are different then we need to map them manually as shown below.

AutoMapper with Nested Types in C#

With the above changes, if we run the application, it will not give us any error, but it will not map the City and State property as shown in the below output.

AutoMapper with Nested Types

This is because we mapped the Address object with the AddressDTO object, but we had not mapped the City and State properties with EmpCity and EmpState properties. Let’s map the above two properties and see what happens. To map the above two properties we need to change the InitializeAutomapper class as shown below.

AutoMapper with Nested Types

With the above changes, now run the application and see the output as expected as shown in the below image.

AutoMapper with Nested Types

In the next article, we will discuss how to map complex type to primitive types using automapper in C#.

SUMMARY:

In this article, I try to explain the AutoMapper Complex Mapping in C# with some examples. I hope this AutoMapper Complex Mapping in C# article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

2 thoughts on “AutoMapper Complex Mapping in C#”

Leave a Reply

Your email address will not be published. Required fields are marked *