C# での AutoMapper ReverseMap

C# の AutoMapper ReverseMap と例

この記事では、 AutoMapper について説明します C# のリバースマップ いくつかの例を示します。 C# で AutoMapper を使用して複合型をプリミティブ型にマップする方法について説明したこの記事に進む前に、以前の記事をお読みください。 例を示します。これは AutoMapper で理解すべき最も重要な概念の 1 つであり、この記事の最後で、c# での automapper リバース マッピングがどのように機能するかを理解できます。

C# の AutoMapper リバース マッピングとは?

Automapper リバース マッピングは、双方向マッピングとも呼ばれる双方向マッピングに他なりません。

ここで説明したマッピングは、たとえばタイプ A とタイプ B の 2 つのタイプがある場合、タイプ A をタイプ B にマップする場合の 1 つの方向の手段です。ただし、Automapper を使用すると、タイプ B をタイプ A に逆マッピングすることも可能です。

C# を理解しよう オートマッパー リバース マッピングと例

このデモでは、次の 3 つのクラスを使用します。

C# で Automapper を使用してリバース マッピングを実装するには、ReverseMap を使用する必要があります。 下の画像に示すようにオプションを選択してください。

以下は完全な例です。

コードは自己説明しました。ですから、コメント行を読んでください。

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

アプリケーションを実行すると、下の画像に示すように、期待どおりにデータが表示されます。

モデルの変更:

以下に示すように、モデルを変更してみましょう。下の画像でわかるように、複合型プロパティが OrderDTO に存在するようになりました クラスとプリミティブ型は Order に存在します クラス。

AutoMapper ReverseMap() を実装しましょう 関数を実行して、期待どおりの結果が得られるかどうかを確認します。以下の画像に示すように、Mapper の初期化を変更して、上記の型のマッピングと逆マッピングを実装します。

以下は完全な例のコードです
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; }
    }
}

アプリケーションを実行して出力を確認してください。

上記の出力からわかるように、オートマッパーのリバース マッピングはプリミティブ型では期待どおりに機能しますが、複合型では機能しません。

したがって、両方のクラスに同じ名前のメンバーがある場合、AutoMapper ReverseMap() 関数は期待どおりに動作します。ただし、クラスに異なるメンバーが含まれており、既定の (命名ごとの) マッピングによってマップされていない場合、これは期待どおりに機能しません。

2 つのマッピングを期待どおりに機能させる方法

双方向マッピングを期待どおりに動作させたい場合は、ForMember を介してマッピングを行う必要があります。そのため、以下の画像に示すように、Mapper の初期化を変更して、複合型のマッピングを伝えます。

以下は完全なコードです。
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; }
    }
}

アプリケーションを実行すると、下の画像に示すように、期待どおりの出力が表示されます。

次の記事では、AutoMapper を使用した条件付きマッピングについて説明します。 C# で例を示します。ここで、この記事では、C# での AutoMapper リバース マッピングについて説明してみます。 例を示します。この C# AutoMapper を期待しています リバースマップ 記事はあなたのニーズに役立ちます。フィードバックをお寄せください。この記事に関するフィードバック、質問、またはコメントを投稿してください。