項目中經常涉及到頁面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更加適合自己的項目。