Asp.Net AutoMapper用法

1、AutoMapper簡介

用於兩個對象映射,例如把Model的屬性值賦值給View Model。傳統寫法會一個一個屬性的映射很麻煩,使用AutoMapper兩句代碼搞定。

2、AutoMapper安裝

推薦使用nuget搜索AutoMapper安裝

3、AutoMapper簡單用法

先建個model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace cms.Web.Models
{public class book
    {
        public int ID { get; set; }
        public string name { get; set; }
        public string className { get; set; }
    }

    public class bookViewModel
    {
        public int ID { get; set; }
        public string name { get; set; }
        public string className { get; set; }
        public int price { get; set; }
        public string des { get; set; }
    }
}

controller代碼

public object ceshi()
        {
            book data = new book { ID = 1, name = "少年1號", className = "娛樂" };

            //映射初始化寫法1
            Mapper.Initialize(x => x.CreateMap<book, bookViewModel>());

            ////映射初始化寫法2
            //Mapper.Initialize(config =>
            //{
            //    config.CreateMap<book, bookViewModel>();

            //});

            ////映射初始化寫法3
            //var cfg = new MapperConfigurationExpression();
            //cfg.CreateMap<book, bookViewModel>();
            //cfg.CreateMap<bookViewModel, book>();
            //Mapper.Initialize(cfg);

            //映射-寫法1:由AutoMapper創建目標對象
            var vmodel = Mapper.Map<book, bookViewModel>(data);

            //映射 - 寫法2:讓AutoMapper把源對象中的屬性值合併 / 覆蓋到目標對象(推薦
            bookViewModel vmodel2 = new bookViewModel();
            Mapper.Map(data, vmodel2);
        Mapper.Reset();//沒有這句代碼刷新頁面會出錯

            //return vmodel.ToString();
            return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(vmodel2));
        }

 

4、AutoMapper擴展類

https://www.cnblogs.com/jianxuanbing/p/7122877.html

很多時候我們使用AutoMapper的時候,都需要進行一個配置纔可以使用Mapper.Map<Source,Target>(entity);。如果不進行配置則會報錯。
如果實體過多,有時候會忘記是否有配置,只有運行的時候纔會發現這個BUG。

該擴展基於AutoMapper 6.x版本,因此需要從Nuget下載相應的包。
該擴展對於Object以及List<T>進行了兼容支持,因此MapTo<TSource,TDestination>()可以直接映射實體與泛型列表。

AutoMapperHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using AutoMapper;
using System.Globalization;
namespace cms.Web.App_Code
{
    public static class AutoMapperHelper
    {
        /// <summary>
        /// 同步鎖
        /// </summary>
        private static readonly object Sync = new object();

        #region MapTo(將源對象映射到目標對象)

        /// <summary>
        /// 將源對象映射到目標對象
        /// </summary>
        /// <typeparam name="TSource">源類型</typeparam>
        /// <typeparam name="TDestination">目標類型</typeparam>
        /// <param name="source">源對象</param>
        /// <param name="destination">目標對象</param>
        /// <returns></returns>
        public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
        {
            return MapTo<TDestination>(source, destination);
        }

        /// <summary>
        /// 將源對象映射到目標對象
        /// </summary>
        /// <typeparam name="TDestination">目標類型</typeparam>
        /// <param name="source">源對象</param>
        /// <returns></returns>
        public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
        {
            return MapTo(source, new TDestination());
        }

        /// <summary>
        /// 將源對象映射到目標對象
        /// </summary>
        /// <typeparam name="TDestination">目標類型</typeparam>
        /// <param name="source">源對象</param>
        /// <param name="destination">目標對象</param>
        /// <returns></returns>
        private static TDestination MapTo<TDestination>(object source, TDestination destination)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source is null");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination is null");
            }
            var sourceType = GetType(source);
            var destinationType = GetType(destination);
            var map = GetMap(sourceType, destinationType);
            if (map != null)
            {
                return Mapper.Map(source, destination);
            }
            lock (Sync)
            {
                map = GetMap(sourceType, destinationType);
                if (map != null)
                {
                    return Mapper.Map(source, destination);
                }
                InitMaps(sourceType, destinationType);
            }
            return Mapper.Map(source, destination);
        }

        /// <summary>
        /// 獲取映射配置
        /// </summary>
        /// <param name="sourceType">源類型</param>
        /// <param name="destinationType">目標類型</param>
        /// <returns></returns>
        private static TypeMap GetMap(Type sourceType, Type destinationType)
        {
            try
            {
                return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
            }
            catch (InvalidOperationException)
            {
                lock (Sync)
                {
                    try
                    {
                        return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
                    }
                    catch (InvalidOperationException)
                    {
                        InitMaps(sourceType, destinationType);
                    }
                    return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
                }
            }
        }

        /// <summary>
        /// 獲取類型
        /// </summary>
        /// <param name="obj">對象</param>
        /// <returns></returns>
        private static Type GetType(object obj)
        {
            var type = obj.GetType();
            if (obj is System.Collections.IEnumerable == false)
            {
                return type;
            }
            if (type.IsArray)
            {
                return type.GetElementType();
            }
            var genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments();
            if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0)
            {
                throw new ArgumentException("泛型類型參數不能爲空");
            }
            return genericArgumentsTypes[0];
        }

        /// <summary>
        /// 初始化映射配置
        /// </summary>
        /// <param name="sourceType">源類型</param>
        /// <param name="destinationType">目標類型</param>
        private static void InitMaps(Type sourceType, Type destinationType)
        {
            try
            {
                var maps = Mapper.Configuration.GetAllTypeMaps();
                Mapper.Initialize(config =>
                {
                    ClearConfig();
                    foreach (var item in maps)
                    {
                        config.CreateMap(item.SourceType, item.DestinationType);
                    }
                    config.CreateMap(sourceType, destinationType);
                });
            }
            catch (InvalidOperationException)
            {
                Mapper.Initialize(config =>
                {
                    config.CreateMap(sourceType, destinationType);
                });
            }
        }

        /// <summary>
        /// 清空配置
        /// </summary>
        private static void ClearConfig()
        {
            var typeMapper = typeof(Mapper).GetTypeInfo();
            var configuration = typeMapper.GetDeclaredField("_configuration");
            configuration.SetValue(null, null, BindingFlags.Static, null, CultureInfo.CurrentCulture);
        }

        #endregion

        #region MapToList(將源集合映射到目標列表)

        /// <summary>
        /// 將源集合映射到目標列表
        /// </summary>
        /// <typeparam name="TDestination">目標元素類型,範例:Sample,不用加List</typeparam>
        /// <param name="source">源集合</param>
        /// <returns></returns>
        public static List<TDestination> MapToList<TDestination>(this System.Collections.IEnumerable source)
        {
            return MapTo<List<TDestination>>(source);
        }

        #endregion
    }
}

用法,非常簡單

public object ceshi()
        {
            bookViewModel vmodel2 = new bookViewModel();

            AutoMapperHelper.MapTo(data, vmodel2);

            return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(vmodel2));
        }
        public object ceshi2()
        {
            dbEntities db = new dbEntities();
            var list = db.news;
            var list2 = AutoMapperHelper.MapToList<news>(list);
            return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(list2));
        }

 

5、AutoMapper高級用法

https://www.cnblogs.com/youring2/p/automapper.html

http://www.cnblogs.com/1-2-3/p/AutoMapper-Best-Practice.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章