回到目录

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(, ErrorMessage = "用户名最多为10个字符")]
public string UserName { get; set; }
[EmailAddress(ErrorMessage = "Email地址不是合法的")]
public string Email { get; set; }
[MaxLength(, 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工具里的通用作法,即先拿出对象,再为指定属性赋新的值,最后提交到数据库!

感谢您的阅读!

回到目录

基础才是重中之重~AutoMapper为已有目标对象映射的更多相关文章

  1. WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对

    WPF MVVM UI分离之<交互与数据分离>   在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...

  2. 基础才是重中之重~关于ThreadStatic和Quartz的一点渊源

    回到目录 ThreadStatic ThreadStatic是C#里的一个特性,它可以让你的字段在一个线程里有效,但你不能控制这个字段在何时被回收,即如果声明一个int32的字段为ThreadStat ...

  3. 基础才是重中之重~方法override详解

    回到 目录 之所以写这篇文章,完全是因为这次代码审核,这次代码审核过程当中,出现了很多我认为基础知识不够扎实的问题,所以,打算把它们记录下来,共大家分享. 方法的override,即方法的覆写或者重写 ...

  4. 基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美

    回到目录 ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单 ...

  5. 基础才是重中之重~stream和byte[]的概念与转化

    回到目录 多看几篇 之所以写这篇文章完全是因为最近在研究FastDFS这个分布式的文件存储系统,当然这不是我第一次研究它了,就像我们去看一本书,我们不会只看一篇,而是一次次,一篇篇,每看一次会有新的收 ...

  6. 基础才是重中之重~理解linq中的groupby

    linq将大部分SQL语句进行了封装,这使得它们更加面向对象了,对于开发者来说,这是一件好事,下面我从基础层面来说一下GroupBy在LINQ中的使用. 对GroupBy的多字段分组,可以看我的这篇文 ...

  7. 基础才是重中之重~lock和monitor的区别

    回到目录 Monitor的介绍 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中 ...

  8. C# 基础才是重中之重~对象的生与死

    为何要写 之所以写这篇文章,完全是因为学生们在实际开发中遇到的问题,一个对象占用的内存空间总不被释放,导致系统内存不断攀升,其最主要原因是我们对“对象的生与死”不清楚,或者从来没有认真去考虑过这件事, ...

  9. 基础才是重中之重~Emit动态构建方法(参数和返回值)

    回到目录 对于Emit我们知道它的可以动态构建程序集,类型,方法,属性等,或者说只要手动使用C#创建的东西使用Emit也都可以动态创建它们,Emit由于它的特别之处,所以在很多领域得到了广泛的应用,像 ...

随机推荐

  1. angular中ng-include失效的原因

    使得angular的ng-include指令失效的原因有两个: 例如:在demo.html中的代码<div ng-include = "'demo1.html'">&l ...

  2. some tips learn from work experience

    1.you can't avoid office politics 2.you'll never have a job which you "can't quit" - if yo ...

  3. Windows server 修改mysql端口

    [此方法对mysql免安装版本适用] (最好先停止mysql服务) 1.解压MySQL后,在MySQL根目录下有一个my-default.ini,将该文件复制粘贴一份,重命名为:my.ini,还是放在 ...

  4. [UCSD白板题] Maximum Pairwise Product

    Problem Description Task.Given a sequence of non-negative integers \(a_0, ..., a_{n-1}\),find the ma ...

  5. c# Invalidate() Update() Refresh()的区别

    Control.Invalidate方法:使控件的特定区域无效并向控件发送绘制消息. 通常情况下,用Invalidate()使区域无效就可触发该控件的重画了,但在一些条件下却没有触发重画.例如: pr ...

  6. 圆角卖萌式登录表单和width的百分比值

    1.圆角恶意卖萌登录表单 小组要做一个网站,大学生社区那种,然后要做登陆界面然后还要做好看的登录界面,然后在书上看到了一个很漂亮的登陆界面,说来和一般的登陆界面没什么不同只是登录表单的边角被柔化了,变 ...

  7. [置顶]PADS PCB功能使用技巧系列之NO.002- 如何走差分线?

    差分信号在高速电路设计中应用越来越广泛,如USB.HDMI.PCI.DDR*等,承载差分信号的差分线主要优势有:抗干扰能力强,能有效抑制EMI.时序定位精确等,对于PCB工程师来说,最关注的是如何确保 ...

  8. java-集合类

    框架图 集合类 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式.数组和集合类同是容器,有何不同?数组存储同一类型的基本数据类 ...

  9. 逐帧动画(Frame-by-frame Animations)

    1.这一类动画可以创建一个Drawable序列,这些Drawable可以按照指定的时间间歇一个一个的显示. xml定义方法 <animation-list xmlns:android=" ...

  10. 利用jmSlip写一个移动端顶部日历选择组件

    可滚动选日期,并限制哪些日期可选和不可选. 主要用来根据后台返回生成一个日期选择器. 具体实现可关注jmslip: https://github.com/jiamao/jmSlip 示例:http:/ ...