基础才是重中之重~AutoMapper为已有目标对象映射
2015-11-13 14:55
429 查看
回到目录
AutoMapper各位一定不会陌生,大叔之前的文章中也提到过,曾经也写过扩展方法,以方便程序开发人员去使用它,而在最近,大叔在一个API项目里,在一个POST请求由DTO对象为实体对象赋值时,出现了一个问题,使用大叔不得不对原有扩展方法再进行二次的补充。
事情是这样的,有一个DTO对象RequestUserInfo和一个数据库实体对象UserInfo,在进行POST时,将RequestUserInfo对象的值需要赋给UserInfo对象,我们知道DTO对象是根据接口要求从UserInfo里提取的,它的属性要少于UserInfo,这在GET请求时,没有出现任何问题(由userinfo到RequestUserInfo的映射),把对应的属性值赋到了DTO对象上面,百在POST时,由于DTO对象的属性少,所以,UserInfo的某些属性没有被赋到值,出现了Null。
以上是两个对象的内容,在AutoMapper的概念里,在GET请求时,UserInfo相当于TSource源对象,RequestUserInfo相当于TResult目标对象,而在POST请求时,这个正好相反,所以我们之前定义的扩展方法就有问题了,它会将UserInfo里的某些属性变成null,这是正常的,因为在进行AutoMapper时,如果你不给它传目标对象,它会自动构建一个新对象。
扩展之前的方法,它AutoMapper支持为已有目标对象赋值
这样在程序调用时,会把已经存在的对象result以参数的形式传入,如下代码
这时entity是从数据库里拿出来的完整数据,再把它的DTO属性进行自动映射赋值,最后把赋值后的对象进行更新!
上面是EF,LINQ这些ORM工具里的通用作法,即先拿出对象,再为指定属性赋新的值,最后提交到数据库!
感谢您的阅读!
回到目录
AutoMapper各位一定不会陌生,大叔之前的文章中也提到过,曾经也写过扩展方法,以方便程序开发人员去使用它,而在最近,大叔在一个API项目里,在一个POST请求由DTO对象为实体对象赋值时,出现了一个问题,使用大叔不得不对原有扩展方法再进行二次的补充。
事情是这样的,有一个DTO对象RequestUserInfo和一个数据库实体对象UserInfo,在进行POST时,将RequestUserInfo对象的值需要赋给UserInfo对象,我们知道DTO对象是根据接口要求从UserInfo里提取的,它的属性要少于UserInfo,这在GET请求时,没有出现任何问题(由userinfo到RequestUserInfo的映射),把对应的属性值赋到了DTO对象上面,百在POST时,由于DTO对象的属性少,所以,UserInfo的某些属性没有被赋到值,出现了Null。
/// <summary> /// DTO 用户-请求参数 /// 输入参数各属性都是可空的,为空时不去验证,并且查询时不去构造查询条件 /// </summary> public class RequestUserInfo : RequestBase { public int? Id { get; set; } [MaxLength(10, ErrorMessage = "用户名最多为10个字符")] public string UserName { get; set; } [EmailAddress(ErrorMessage = "Email地址不是合法的")] public string Email { get; set; } [MaxLength(20, ErrorMessage = "用户名最多为20个字符")] public string RealName { get; set; } }
public class UserInfo : Entity { [DisplayName("用户名"), Required]// StringLength(50, MinimumLength = 4, ErrorMessage = "用户名只能由~50个字符组成") public string UserName { get; set; } [DisplayName("真实姓名"), Required]//StringLength(30, MinimumLength = 6, ErrorMessage = "真实姓名只能由6~30个字符组成") public string RealName { get; set; } [DisplayName("密码"), Required]// StringLength(20, MinimumLength = 6, ErrorMessage = "密码由6~20个字符组成") public string Password { get; set; } [DisplayName("电子邮件"), Required, EmailAddress] public string Email { get; set; } }
以上是两个对象的内容,在AutoMapper的概念里,在GET请求时,UserInfo相当于TSource源对象,RequestUserInfo相当于TResult目标对象,而在POST请求时,这个正好相反,所以我们之前定义的扩展方法就有问题了,它会将UserInfo里的某些属性变成null,这是正常的,因为在进行AutoMapper时,如果你不给它传目标对象,它会自动构建一个新对象。
扩展之前的方法,它AutoMapper支持为已有目标对象赋值
/// <summary> /// 为已经存在的对象进行automapper /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="self"></param> /// <param name="result"></param> /// <returns></returns> public static TResult MapTo<TResult>(this object self, TResult result) { if (self == null) throw new ArgumentNullException(); Mapper.CreateMap(self.GetType().UnderlyingSystemType, typeof(TResult)); return (TResult)Mapper.Map(self, result, self.GetType(), typeof(TResult)); }
这样在程序调用时,会把已经存在的对象result以参数的形式传入,如下代码
public void Update(RequestUserInfo request) { var entity = userRepository.GetModel().FirstOrDefault(i => i.Id == request.Id); request.MapTo<UserInfo>(entity); userRepository.Update(entity); }
这时entity是从数据库里拿出来的完整数据,再把它的DTO属性进行自动映射赋值,最后把赋值后的对象进行更新!
上面是EF,LINQ这些ORM工具里的通用作法,即先拿出对象,再为指定属性赋新的值,最后提交到数据库!
感谢您的阅读!
回到目录
相关文章推荐
- isIOS9
- 【iOS开发】更改来自友盟社会化组件
- 例说android静态JNI调用C/C++代码——HelloWorld
- Cocos2D旋转炮塔到指定角度(三)
- Cocos2D旋转炮塔到指定角度(三)
- Cocos2D旋转炮塔到指定角度(三)
- android ListView 单条刷新方法实践及原理解析
- Objective C类方法load和initialize的区别
- android shape的使用
- Android的Fragment中onActivityResult不被调用的解决方案(绝对管用)
- iOS应用安全防护框架概述
- Swift函数
- Android系统移植与调试之------->如何修改Android系统默认显示【开发者选项】并默认打开【USB调试】和【未知来源】开关
- Android 编程下字库的使用
- Swift
- Android属性动画完全解析(上)
- 你追我赶进度条
- ajax获取的全部是object,我要获取的是json
- android开发的学习路线
- IOSFunction