AutoMapper ReverseMap en C#

AutoMapper ReverseMap en C#

AutoMapper ReverseMap en C# con ejemplos

En este artículo, voy a hablar sobre el AutoMapper ReverseMap en C# con algunos ejemplos. Lea nuestro artículo anterior antes de continuar con este artículo donde discutimos cómo mapear el tipo complejo al tipo primitivo usando AutoMapper en C# con ejemplos Este es uno de los conceptos más importantes para entender en AutoMapper y al final de este artículo, comprenderá cómo funciona el mapeo inverso de automapper en C#.

¿Qué es el mapeo inverso de AutoMapper en C#?

El mapeo inverso de Automapper no es más que el mapeo bidireccional, también llamado mapeo bidireccional.

A partir de ahora, el mapeo que discutimos es un medio direccional si tenemos dos tipos, digamos Tipo A y Tipo B, entonces mapeamos Tipo A con Tipo B. Pero usando Automapper Mapeo inverso también es posible Mapear el Tipo B con el Tipo A.

Entendamos C# AutoMapeador Asignación inversa con un ejemplo.

Vamos a utilizar las siguientes tres clases para esta demostración.

Para implementar el mapeo inverso usando Automapper en C# necesitamos usar el ReverseMap opción como se muestra en la imagen de abajo.

A continuación se muestra el ejemplo completo.

El código se explica por sí mismo. Por lo tanto, revise las líneas de comentarios.

using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Initialize the Mapper
            var mapper = InitializeAutomapper();

            //Step2: Create the Order Request
            var OrderRequest = CreateOrderRequest();

            //Step3: Map the OrderRequest object to Order DTO
            var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest);

            //Step4: Print the OrderDTO Data
            Console.WriteLine("After Mapping - OrderDTO Data");
            Console.WriteLine("OrderId : " + orderDTOData.OrderId);
            Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
            Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
            Console.WriteLine("CustomerId : " + orderDTOData.CustomerId);
            Console.WriteLine("Name : " + orderDTOData.Name);
            Console.WriteLine("Postcode : " + orderDTOData.Postcode);
            Console.WriteLine("MobileNo : " + orderDTOData.MobileNo);
            Console.WriteLine();

            //Step5: modify the OrderDTO data
            orderDTOData.OrderId = 10;
            orderDTOData.NumberOfItems = 20;
            orderDTOData.TotalAmount = 2000;
            orderDTOData.CustomerId = 5;
            orderDTOData.Name = "Smith";
            orderDTOData.Postcode = "12345";

            //Step6: Reverse Map
            mapper.Map(orderDTOData, OrderRequest);

            //Step7: Print the Order Data
            Console.WriteLine("After Reverse Mapping - Order Data");
            Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
            Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
            Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
            Console.WriteLine("CustomerId : " + OrderRequest.Customer.CustomerID);
            Console.WriteLine("FullName : " + OrderRequest.Customer.FullName);
            Console.WriteLine("Postcode : " + OrderRequest.Customer.Postcode);
            Console.WriteLine("ContactNo : " + OrderRequest.Customer.ContactNo);
            Console.ReadLine();
        }

        private static Order CreateOrderRequest()
        {
            return new Order
            {
                OrderNo = 101,
                NumberOfItems = 3,
                TotalAmount = 1000,
                Customer = new Customer()
                {
                    CustomerID = 777,
                    FullName = "James Smith",
                    Postcode = "755019",
                    ContactNo = "1234567890"
                },
            };
        }

        static Mapper InitializeAutomapper()
        {

            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Order, OrderDTO>()
                    //OrderId is different so map them using For Member
                    .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))

                    //Customer is a Complex type, so Map Customer to Simple type using For Member
                    .ForMember(dest => dest.Name, act => act.MapFrom(src => src.Customer.FullName))
                    .ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.Customer.Postcode))
                    .ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.Customer.ContactNo))
                    .ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.Customer.CustomerID))
                    .ReverseMap();
            });
            
            var mapper = new Mapper(config);
            return mapper;
        }
    }

    public class Order
    {
        public int OrderNo { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public Customer Customer { get; set; }
    }
    public class Customer
    {
        public int CustomerID { get; set; }
        public string FullName { get; set; }
        public string Postcode { get; set; }
        public string ContactNo { get; set; }
    }
    public class OrderDTO
    {
        public int OrderId { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public int CustomerId { get; set; }
        public string Name { get; set; }
        public string Postcode { get; set; }
        public string MobileNo { get; set; }
    }
}

Cuando ejecuta la aplicación, muestra los datos como se esperaba, como se muestra en la imagen a continuación.

Modificación de modelos:

Modifiquemos los modelos como se muestra a continuación. Como puede ver en la imagen de abajo, ahora la propiedad de tipo complejo está presente en OrderDTO la clase y los tipos primitivos están presentes en el Orden clase.

Implementemos el AutoMapper ReverseMap() función y ver si obtenemos los resultados esperados o no. Modifique la inicialización de Mapper para implementar el mapeo y el mapeo inverso para los tipos anteriores, como se muestra en la imagen a continuación.

A continuación se muestra el código del ejemplo completo
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Initialize the Mapper
            var mapper = InitializeAutomapper();

            //Step2: Create the Order Request
            var OrderRequest = CreateOrderRequest();

            //Step3: Map the OrderRequest object to Order DTO
            var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest);

            //Step4: Print the OrderDTO Data
            Console.WriteLine("After Mapping - OrderDTO Data");
            Console.WriteLine("OrderId : " + orderDTOData.OrderId);
            Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
            Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
            Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID);
            Console.WriteLine("FullName : " + orderDTOData.customer.FullName);
            Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode);
            Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo);
            Console.WriteLine();

            //Step5: modify the OrderDTO data
            orderDTOData.OrderId = 10;
            orderDTOData.NumberOfItems = 20;
            orderDTOData.TotalAmount = 2000;
            orderDTOData.customer.CustomerID = 5;
            orderDTOData.customer.FullName = "James Smith";
            orderDTOData.customer.Postcode = "12345";

            //Step6: Reverse Map
            mapper.Map(orderDTOData, OrderRequest);

            //Step7: Print the Order Data
            Console.WriteLine("After Reverse Mapping - Order Data");
            Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
            Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
            Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
            Console.WriteLine("CustomerId : " + OrderRequest.CustomerId);
            Console.WriteLine("Name : " + OrderRequest.Name);
            Console.WriteLine("Postcode : " + OrderRequest.Postcode);
            Console.WriteLine("MobileNo : " + OrderRequest.MobileNo);
            Console.ReadLine();
        }

        private static Order CreateOrderRequest()
        {
            return new Order
            {
                OrderNo = 101,
                NumberOfItems = 3,
                TotalAmount = 1000,
                CustomerId = 777,
                Name = "James Smith",
                Postcode = "755019",
                MobileNo = "1234567890"
            };
        }

        static Mapper InitializeAutomapper()
        {

            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Order, OrderDTO>()
                    .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))
                    .ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer()
                    {
                        CustomerID = src.CustomerId,
                        FullName = src.Name,
                        Postcode = src.Postcode,
                        ContactNo = src.MobileNo
                    }))
                    .ReverseMap();
            });
            
            var mapper = new Mapper(config);
            return mapper;
        }
    }

    public class Order
    {
        public int OrderNo { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public int CustomerId { get; set; }
        public string Name { get; set; }
        public string Postcode { get; set; }
        public string MobileNo { get; set; }
    }
    public class Customer
    {
        public int CustomerID { get; set; }
        public string FullName { get; set; }
        public string Postcode { get; set; }
        public string ContactNo { get; set; }
    }
    public class OrderDTO
    {
        public int OrderId { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public Customer customer { get; set; }
    }
}

Ahora ejecute la aplicación y vea el resultado.

Como puede ver en el resultado anterior, el mapeo inverso del mapeador automático funciona como se esperaba para los tipos primitivos pero no funciona para el tipo complejo.

Entonces, cuando ambas clases tienen miembros con el mismo nombre, AutoMapper ReverseMap() la función funciona como se esperaba. Pero si las clases contienen miembros que son diferentes y no se asignan a través de la asignación predeterminada (por nombre), esto no funciona como se esperaba.

¿Cómo hacer que los dos mapeos funcionen como se esperaba?

Si desea que el mapeo bidireccional funcione como se espera, debe realizar el mapeo a través de ForMember. Así que modifique la inicialización de Mapper para indicar el mapeo para el tipo complejo como se muestra en la imagen a continuación.

A continuación se muestra el código completo.
using System;
using AutoMapper;
namespace AutoMapperDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Step1: Initialize the Mapper
            var mapper = InitializeAutomapper();

            //Step2: Create the Order Request
            var OrderRequest = CreateOrderRequest();

            //Step3: Map the OrderRequest object to Order DTO
            var orderDTOData = mapper.Map<Order, OrderDTO>(OrderRequest);

            //Step4: Print the OrderDTO Data
            Console.WriteLine("After Mapping - OrderDTO Data");
            Console.WriteLine("OrderId : " + orderDTOData.OrderId);
            Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
            Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
            Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID);
            Console.WriteLine("FullName : " + orderDTOData.customer.FullName);
            Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode);
            Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo);
            Console.WriteLine();

            //Step5: modify the OrderDTO data
            orderDTOData.OrderId = 10;
            orderDTOData.NumberOfItems = 20;
            orderDTOData.TotalAmount = 2000;
            orderDTOData.customer.CustomerID = 5;
            orderDTOData.customer.FullName = "James Smith";
            orderDTOData.customer.Postcode = "12345";

            //Step6: Reverse Map
            mapper.Map(orderDTOData, OrderRequest);

            //Step7: Print the Order Data
            Console.WriteLine("After Reverse Mapping - Order Data");
            Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
            Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
            Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
            Console.WriteLine("CustomerId : " + OrderRequest.CustomerId);
            Console.WriteLine("Name : " + OrderRequest.Name);
            Console.WriteLine("Postcode : " + OrderRequest.Postcode);
            Console.WriteLine("MobileNo : " + OrderRequest.MobileNo);
            Console.ReadLine();
        }

        private static Order CreateOrderRequest()
        {
            return new Order
            {
                OrderNo = 101,
                NumberOfItems = 3,
                TotalAmount = 1000,
                CustomerId = 777,
                Name = "James Smith",
                Postcode = "755019",
                MobileNo = "1234567890"
            };
        }

        static Mapper InitializeAutomapper()
        {
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Order, OrderDTO>()

                     .ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))
                     .ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer()
                     {
                         CustomerID = src.CustomerId,
                         FullName = src.Name,
                         Postcode = src.Postcode,
                         ContactNo = src.MobileNo
                     }))

                     .ReverseMap()

                     .ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.customer.CustomerID))
                     .ForMember(dest => dest.Name, act => act.MapFrom(src => src.customer.FullName))
                     .ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.customer.ContactNo))
                     .ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.customer.Postcode));

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

    public class Order
    {
        public int OrderNo { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public int CustomerId { get; set; }
        public string Name { get; set; }
        public string Postcode { get; set; }
        public string MobileNo { get; set; }
    }
    public class Customer
    {
        public int CustomerID { get; set; }
        public string FullName { get; set; }
        public string Postcode { get; set; }
        public string ContactNo { get; set; }
    }
    public class OrderDTO
    {
        public int OrderId { get; set; }
        public int NumberOfItems { get; set; }
        public int TotalAmount { get; set; }
        public Customer customer { get; set; }
    }
}

Ahora ejecuta la aplicación y verás el resultado esperado como se muestra en la imagen de abajo.

En el próximo artículo, voy a hablar sobre Asignación condicional usando AutoMapper en C# con ejemplos. Aquí, en este artículo, intento explicar la asignación inversa de AutoMapper en C# con ejemplos Espero que este C# AutoMapper Mapa inverso artículo le ayudará con su necesidad. Me gustaría tener sus comentarios. Publique sus comentarios, preguntas o comentarios sobre este artículo.