Mappatura complessa di AutoMapper in C#

Mappatura complessa di AutoMapper in C#

Mappatura complessa di AutoMapper in C# con esempi

In questo articolo parlerò della Mappatura complessa di AutoMapper in C# con alcuni esempi. Leggi il nostro articolo precedente prima di passare a questo articolo in cui abbiamo discusso le basi di Automapper in C# con alcuni semplici esempi. Alla fine di questo articolo capirai cos'è AutoMapper Complex Mapping e quando e come utilizzare AutoMapper Complex Mapping in C# con esempi.

Che cos'è Mappatura complessa di AutoMapper in C#?

Quando entrambi i tipi coinvolti nella mappatura contengono proprietà di tipo complesso, in tali scenari è necessario utilizzare la mappatura complessa di AutoMapper in C#. Cerchiamo di comprendere la mappatura complessa di AutoMapper con un esempio. Utilizzeremo le seguenti quattro classi per questa demo.

Requisito aziendale :

Il nostro requisito è mappare il Dipendente opporsi a EmployeeDTO oggetto. Per semplificare questa demo, qui abbiamo creato entrambe le classi con gli stessi nomi di proprietà. Ma la cosa che dobbiamo tenere a mente qui è che abbiamo creato la proprietà address come un tipo complesso. Quindi stiamo creando un metodo statico, ad esempio InitializeAutomapper dove scriviamo il codice di mappatura come mostrato nell'immagine sottostante.

Di seguito è riportato il codice completo.
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Create and populate the Employee object
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee
            {
                Name = "James",
                Salary = 20000,
                Department = "IT",
                address = empAddres
            };

            var mapper =InitializeAutomapper();
            var empDTO = mapper.Map<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 Mapper InitializeAutomapper()
        {
            var config = new MapperConfiguration(cfg => {             
                cfg.CreateMap<Employee, EmployeeDTO>();
            });

            var mapper = new Mapper(config);
            return mapper;
        }
    }

    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; }
    }
}

Ora, quando esegui l'applicazione, otterrai la seguente eccezione di runtime.

Ora, se vai all'eccezione interna e controlli la proprietà del messaggio, mostra chiaramente che la configurazione del tipo di mappatura manca per Address e AddressDTO. Questo perché nella nostra configurazione del mapper, abbiamo specificato il Mapper per Employee e EmployeeDTO ma non per il tipo Address e AddressDTO.

Come risolvere il problema di cui sopra?

Per risolvere il problema di cui sopra, è necessario configurare la mappatura tra Address e AddressDTO, prima della mappatura Employee e EmployeeDTO. Quindi, cambia InitializeAutomapper metodo come mostrato di seguito.

Con le modifiche precedenti in atto, ora, se esegui l'applicazione e poi otterrai l'output come previsto, come mostrato nell'immagine sottostante.

Cosa succede se cambiamo il nome della proprietà di tipo complesso coinvolto nell'automapper?

Capiamolo con un esempio. Cambiamo l'indirizzo della proprietà complessa in addressDTO della classe EmployeeDTO come mostrato di seguito.

Di seguito è riportato il codice completo.
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee
            {
                Name = "James",
                Salary = 20000,
                Department = "IT",
                address = empAddres
            };

            var mapper =InitializeAutomapper();
            var empDTO = mapper.Map<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 Mapper InitializeAutomapper()
        {
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Address, AddressDTO>();
                cfg.CreateMap<Employee, EmployeeDTO>();
            });

            var mapper = new Mapper(config);
            return mapper;
        }
    }

    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; }
    }
}

Ora esegui l'applicazione. Dovrebbe darti il ​​seguente errore.

Questo perché il nome della proprietà per addressDTO non si trova nel Dipendente oggetto. Quindi otteniamo l'errore di riferimento nullo.

Come risolvere il problema di cui sopra?

Per risolvere il problema di cui sopra, dobbiamo mappare l'indirizzo proprietà a addressDTO proprietà nella configurazione del mappatore come mostrato nell'immagine sottostante.

Con le modifiche precedenti nella configurazione di automapper, ora esegui l'applicazione e ti darà il risultato come previsto.

Cosa succede se i nomi delle proprietà di tipo Complesso sono diversi?

Capiamolo con un esempio. Modifichiamo i nomi delle proprietà in AddressDTO classe come mostrato di seguito.

Di seguito è riportato l'esempio completo.
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee
            {
                Name = "James",
                Salary = 20000,
                Department = "IT",
                address = empAddres
            };

            var mapper =InitializeAutomapper();
            var empDTO = mapper.Map<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 Mapper InitializeAutomapper()
        {
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Address, AddressDTO>();
                cfg.CreateMap<Employee, EmployeeDTO>()
                .ForMember(dest => dest.addressDTO, act => act.MapFrom(src => src.address));
            });

            var mapper = new Mapper(config);
            return mapper;
        }
    }

    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; }
    }
}

Quando esegui l'applicazione, non visualizzerai alcun errore, ma non mapperà la Città e Stato proprietà come mostrato nell'output di seguito.

Questo perché abbiamo mappato l'indirizzo oggetto con AddressDTO oggetto, ma non abbiamo mappato la Città e Stato proprietà con EmpCity e EmpState proprietà. Mappiamo le due proprietà sopra e vediamo cosa succede. Per mappare le due proprietà precedenti, è necessario modificare InitializeAutomapper classe come mostrato di seguito.

Il codice completo è riportato di seguito:
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Address empAddres = new Address()
            {
                City = "Mumbai",
                Stae = "Maharashtra",
                Country = "India"
            };

            Employee emp = new Employee
            {
                Name = "James",
                Salary = 20000,
                Department = "IT",
                address = empAddres
            };

            var mapper =InitializeAutomapper();
            var empDTO = mapper.Map<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 Mapper InitializeAutomapper()
        {
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Address, AddressDTO>()
                .ForMember(dest => dest.EmpCity, act => act.MapFrom(src => src.City))
                    .ForMember(dest => dest.EmpStae, act => act.MapFrom(src => src.Stae)); ;
                cfg.CreateMap<Employee, EmployeeDTO>()
                .ForMember(dest => dest.addressDTO, act => act.MapFrom(src => src.address));
            });

            var mapper = new Mapper(config);
            return mapper;
        }
    }

    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; }
    }
}

Con le modifiche precedenti in atto, ora esegui l'applicazione e vedi l'output come previsto, come mostrato nell'immagine sottostante.

Nel prossimo articolo, discuteremo come mappare tipo complesso a tipi primitivi utilizzando automapper in C#. In questo articolo, provo a spiegare la mappatura complessa di AutoMapper in C# con alcuni esempi. Spero che questo Mappatura complessa di AutoMapper in C# l'articolo ti aiuterà con il tuo bisogno. Mi piacerebbe avere il tuo feedback. Pubblica il tuo feedback, domanda o commenti su questo articolo.