项目中经常涉及到页面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?,是否含有Columnobject[] 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("用户信息更新成功!"));elsereturn Json(ResultMsg.Failure("用户信息更新失败,请您重试!"));}
写在后面
自己实现,相对来说,自由度高了很多,你可以自己扩展方法,实现客制化的DTO转Entity,让AutoMapper更加适合自己的项目。