自制AutoMapper实现DTO到持久层Entity的转换

自制AutoMapper实现DTO到持久层Entity的转换

项目中经常涉及到页面DTO更新,保存到数据库的操作,这就必然牵扯到DTO和持久层对象的转换,常见的第三方库有:

java:dozer

.net: AutoMapper

看到AutoMapper已经许久没更新了,而且项目中没必要用这么大的东西,于是自己实现了一个简易DTO到Entity的转换器。

实现的功能

自定义的AutoMapper主要实现了如下几点功能:

1.DTO字段忽略转换

[AutoMapping(Ignore=true)]
public DateTime CreateTime { get; set; }

2.DTO字段和Entity的强制映射

[AutoMapping(EntityColumn="Sex")]
public string XingBie { get; set; }

3.默认DTO和Entity字段相同的,自动转换

核心代码:

复制代码
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Linq;

namespace ElegantWM.AutoMapper
{
    public class AutoMapper<T1,T2> where T1:new() where T2:new()
    {
        /// <summary>
        /// DTO 转换为 Entity
        /// </summary>
        /// <typeparam name="T1">DTO</typeparam>
        /// <typeparam name="T2">Entity</typeparam>
        /// <param name="t1">Dto</param>
        /// <param name="t2">Entity</param>
        /// <returns></returns>
        public static T2 Convert(T1 t1, T2 t2)
        {
            var dtoProperList = t1.GetType().GetProperties().Where(p => p.PropertyType.IsPublic == true).ToList();
            var entityProperList = t2.GetType().GetProperties().Where(p => p.PropertyType.IsPublic == true).ToList();
            foreach (System.Reflection.PropertyInfo pi in dtoProperList)
            {
                string realName=pi.Name;
                //首先判断列是否ignore?,是否含有Column
                object[] cusAttrs = pi.GetCustomAttributes(typeof(AutoMappingAttribute), true);
                if (cusAttrs.Length > 0)
                {
                    AutoMappingAttribute attr = cusAttrs[0] as AutoMappingAttribute;
                    if (attr.Ignore)
                        continue;
                    if (!string.IsNullOrEmpty(attr.EntityColumn))
                        realName = attr.EntityColumn;
                }
                var entityPi = entityProperList.Single(p => p.Name == realName);
                if (entityPi == null)
                    continue;
                object value = pi.GetValue(t1, null);
                if (value == null)
                    continue;
                entityPi.SetValue(t2, value, null);                
            }
            return t2;
        }
    }
}
复制代码
案例

持久层Entity的定义如下:

复制代码
public class Entity:IEntity
    {
        public Guid Id { get; set; }
        public string CreateUser { get; set; }
        public DateTime CreateTime { get; set; }
        public string ModifyUser { get; set; }
        public DateTime? ModifyTime { get; set; }
        [Timestamp]
        public Byte[] RowVersion { get; set; }
    }   
 public class WMS_User : Entity
    {
        public WMS_User() { }

        public string UserName { get; set; }
        public string NickName { get; set; }
        public string UserPwd { get; set; }
        public string Sex { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string QQ { get; set; }
        public string Address { get; set; }
        public string Remark { get; set; }
        public bool Disable { get; set; }
        public virtual ICollection<WMS_OrgUser> UserOrgIds { get; set; }
    }
复制代码

页面DTO定义如下:

复制代码
public class UserDto
    {
        public UserDto() { }
        public Guid Id { get; set; }
        public string UserName { get; set; }
        public string NickName { get; set; }       
        public string UserPwd { get; set; }
        //强制字段映射
        [AutoMapping(EntityColumn="Sex")]
        public string XingBie { get; set; }

        public string Phone { get; set; }
        public string Email { get; set; }
        public string QQ { get; set; }
        public string Address { get; set; }
        public string Remark { get; set; }
        public bool Disable { get; set; }
        //忽略字段映射
        [AutoMapping(Ignore=true)]
        public DateTime CreateTime { get; set; }
    }    
复制代码

使用AutoMapper,做转换:

复制代码
     [Action]
        [Description("更新用户")]
        [HttpPut]
        public JsonResult Update(UserDto user)
        {
            WMS_User userEntity = WMFactory.WMSUser.GetById(user.Id.ToString());
//*******看这里哦********
            userEntity = AutoMapper<UserDto, WMS_User>.Convert(user, userEntity);
            if (WMFactory.WMSUser.Update(userEntity))
                return Json(ResultMsg.Success("用户信息更新成功!"));
            else
                return Json(ResultMsg.Failure("用户信息更新失败,请您重试!"));
        }
复制代码
写在后面

自己实现,相对来说,自由度高了很多,你可以自己扩展方法,实现客制化的DTO转Entity,让AutoMapper更加适合自己的项目。

如果您认可我的工作,并且觉得本文对您有所帮助,可以通过支付宝或转发文章的方式资助我们,我们愿意接受来自各方面的捐赠。再次感谢您对开源事业的赞助和支持!
文章部分内容可能摘自网络,如果侵犯您的权益,请及时联系我,谢谢.

作者:JackChain
 
分类: .Net软件架构
原文地址:https://www.cnblogs.com/Leo_wl/p/3174147.html