• 8分钟学会使用AutoMapper


    一.什么是AutoMapper与为什么用它。

    它是一种对象与对象之间的映射器,让AutoMapper有意思的就是在于它提供了一些将类型A映射到类型B这种无聊的实例,只要B遵循AutoMapper已经建立的惯例,那么大多数情况下就可以进行相互映射了。

    二.如何使用?

    直接nuget install-package automapper 简单到不能再简单了。

    三.入门

    定义了连个简单的Model:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void Main(string[] args)
            {
                Destination des = new Destination()
                {
                    InfoUrl = "www.cnblogs.com/zaranet",
                    name ="张子浩"
                };
                Mapper.Initialize(x => x.CreateMap<Destination, Source>());
                Source source = AutoMapper.Mapper.Map<Source>(des);
                Console.WriteLine(source.InfoUrl);
            }

      Initialize方法是Mapper的初始化,里面可以写上CreateMap表达式,具体是谁和谁进行匹配。在之后就可以直接进行一个获取值的过程了,非常的简单。

    四.映射前后操作

    偶尔有的时候你可能需要在映射的过程中,你需要执行一些逻辑,这是非常常见的事情,所以AutoMapper给我们提供了BeforeMap和AfterMap两个函数。

    1
    2
    3
    Mapper.Initialize(x => x.CreateMap<Destination, Source>().BeforeMap(
                    (src,dest)=>src.InfoUrl ="https://"+src.InfoUrl).AfterMap(
                    (src,dest)=>src.name="真棒"+src.name));

    其中呢,src是Destination对象,dest是Source,你呢就可以用这两个对象去获取里面的值,说白了这就是循环去找里面的值了。

     五.条件映射

    1
    Mapper.Initialize(x => x.CreateMap<Destination, Source>().ForMember(dest => dest.InfoUrl,opt => opt.Condition(dest => dest.InfoUrl == "www.cnblogs.com/zaranet1")).ForMember(...(.ForMember(...))));

    在条件映射中,通过ForMember函数,参数是一个委托类型Fun<>,其里面呢也是可以进行嵌套的,但一般来说一个就够用了。

    六.AutoMapper配置

    初始化配置是非常受欢迎的,每个领域都应该配置一次。

    1
    2
    3
    4
    5
    //初始化配置文件
    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<Aliens, Person>();
    });

     但是像这种情况呢,如果是多个映射,那么我们只能用Profile来配置,组织你的映射配置,并将配置放置到构造函数中(这种情况是5.x以上的版本),一个是以下的版本,已经被淘汰了。

    5.0及以上版本:

    1
    2
    3
    4
    5
    6
    7
    public class AliensPersonProfile : Profile
        {
            public AliensPersonProfile()
            {
                CreateMap<Destination, Source>();
            }
        }

    5.0以下版本(在早期版本中,使用配置方法而不是构造函数。 从版本5开始,Configure()已经过时。 它将在6.0中被删除。)

    1
    2
    3
    4
    5
    6
    7
    public class OrganizationProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<Foo, FooDto>();
        }
    }

     然后在程序启动的时候初始化即可。

    1
    Mapper.Initialize(x=>x.AddProfile<AliensPersonProfile>());

    七.AutoMapper的最佳实践

    上文中已经说到了AutoMapper的简单映射,但是在实际项目中,我们应该有很多类进行映射,这么多的映射应该怎么组织,这是一个活生生的问题,这成为主映射器。

    在主映射器中,组织了多个小映射器,Configuration为我们的静态配置入口类;Profiles文件夹为我们所有Profile类的文件夹。如果是MVC,我们需要在Global中调用,那我的这个是控制台的。

    1
    2
    3
    4
    5
    6
    7
    8
    public static void Configure()
            {
                Mapper.Initialize(cfg =>
                {
                    cfg.AddProfile<DestinationSourceProfile>();
                    cfg.AddProfile(new StudentSourceProfile());
                });
            }

    其中添加子映射,可以用以上两种方式。

    1
    2
    3
    4
    public void Configuration(IAppBuilder app)
            {
                AutoMapperConfiguration.Configure();
            }

    八.指定映射字段

    在实际业务环境中,你不可能说两个类的字段是一 一 对应的,这个时候我们就要对应它们的映射关系。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class CalendarEvent
    {
        public DateTime Date { getset; }
        public string Title { getset; }
    }
     
    public class CalendarEventForm
    {
        public DateTime EventDate { getset; }
        public int EventHour { getset; }
        public int EventMinute { getset; }
        public string DisplayTitle { getset; }
    }

    在这两个类中,CalendarEvent的Date将被拆分为CalendarEventForm的日期、时、分三个字段,Title也将对应DisplayTitle字段,那么相应的Profile定义如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class CalendarEventProfile : Profile
       {
           public CalendarEventProfile()
           {
               CreateMap<CalendarEvent, CalendarEventForm>()
              .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
              .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
              .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute))
              .ForMember(dest => dest.DisplayTitle, opt => opt.MapFrom(src => src.Title));
           }
       }

     main方法通过依赖注入,开始映射过程,下图是代码和图。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void Main(string[] args)
            {
                CalendarEvent calendar = new CalendarEvent()
                {
                    Date = DateTime.Now,
                    Title = "Demo Event"
                };
                AutoMapperConfiguration.Configure();
                CalendarEventForm calendarEventForm = Mapper.Map<CalendarEventForm>(calendar);
                Console.WriteLine(calendarEventForm);
            }   

      

    那么最后呢,如果是反向的映射,一定回缺少属性,那么就你就可以obj.属性进行赋值。

    附AutoHelper封装类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    /// <summary>
        /// AutoMapper扩展帮助类
        /// </summary>
        public static class AutoMapperHelper
        {
            /// <summary>
            ///  类型映射
            /// </summary>
            public static T MapTo<T>(this object obj)
            {
                if (obj == nullreturn default(T);
                Mapper.CreateMap(obj.GetType(), typeof(T));
                return Mapper.Map<T>(obj);
            }
            /// <summary>
            /// 集合列表类型映射
            /// </summary>
            public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
            {
                foreach (var first in source)
                {
                    var type = first.GetType();
                    Mapper.CreateMap(type, typeof(TDestination));
                    break;
                }
                return Mapper.Map<List<TDestination>>(source);
            }
            /// <summary>
            /// 集合列表类型映射
            /// </summary>
            public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
            {
                //IEnumerable<T> 类型需要创建元素的映射
                Mapper.CreateMap<TSource, TDestination>();
                return Mapper.Map<List<TDestination>>(source);
            }
            /// <summary>
            /// 类型映射
            /// </summary>
            public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
                where TSource : class
                where TDestination : class
            {
               if (source == nullreturn destination;
                Mapper.CreateMap<TSource, TDestination>();
                return Mapper.Map(source, destination);
            }
            /// <summary>
            /// DataReader映射
            /// </summary>
            public static IEnumerable<T> DataReaderMapTo<T>(this IDataReader reader)
            {
                Mapper.Reset();
                Mapper.CreateMap<IDataReader, IEnumerable<T>>();
                return Mapper.Map<IDataReader, IEnumerable<T>>(reader);
            }
        }
    }
  • 相关阅读:
    ASP.NET Core 中的配置
    依赖注入简介
    Authoriztion Code Flow
    建立IdentityServer项目
    OAuth2 OpenID Connect概述
    Asp.Net Core 项目运行部署到发布
    javascript Template tmpl
    webform ajax 异步请求
    hosts 文件
    webform 使用富文本编辑器
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/12217725.html
Copyright © 2020-2023  润新知