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