ToB企服应用市场:ToB评测及商务社交产业平台

标题: C# DAO转换为DTO工具类 [打印本页]

作者: 饭宝    时间: 2023-12-14 19:19
标题: C# DAO转换为DTO工具类
思想

DAO(Data Access Object)数据访问对象,是我们在做结构化数据库访问的时候传输的对象,通过这个对象我们可以与数据库中的表建立映射关系
DTO(Data Transfer Object)是我们在与前端进行数据交换时传递的对象

为什么需要设置这这两种对象呢?


转换思路

我们这里既然要转换肯定是无论是基础类型还是引用类型的属性都可以转换,所以我想到了利用反射
步骤:

代码实现

来源类型
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace Model.Entity
  7. {
  8.     public class User
  9.     {
  10.         public int UserId { get; set; }
  11.         // QQ邮箱
  12.         public string QQEmail { get; set; }
  13.         // 昵称
  14.         public string Nickname { get; set; }
  15.         // 密码
  16.         public string Password { get; set; }
  17.         // 用户状态 0:表示online 1:表示离线 2:表示对战中,-1:表示禁止登录
  18.         public int Status { get; set; }
  19.         // 是否是管理员 0:不是 1:是
  20.         public bool IsAdmin { get; set; }
  21.         // 用户的头像
  22.         public string AvatarUrl { get; set; }
  23.         // 获胜的场数
  24.         public int WinNumber { get; set; }
  25.         // 失败的场数
  26.         public int LoseNumber { get; set; }
  27.         // 和棋的场数
  28.         public int DrawNumber { get; set; }
  29.         // 排名
  30.         public int RankNumber { get; set; }
  31.         // 创建时间
  32.         public DateTime CreateTime { get; set; }
  33.         // 修改时间
  34.         public DateTime UpdateTime { get; set; }
  35.     }
  36. }
复制代码
目标类型
  1. namespace gobangBack.DTO
  2. {
  3.     public record UserDTO
  4.     {
  5.         public int UserId { get; set; }
  6.         // QQ邮箱
  7.         public string QQEmail { get; set; }
  8.         // 昵称
  9.         public string Nickname { get; set; }
  10.         // 用户状态 0:表示online 1:表示离线 2:表示对战中,-1:表示禁止登录
  11.         public int Status { get; set; }
  12.         // 是否是管理员 0:不是 1:是
  13.         public bool IsAdmin { get; set; }
  14.         // 用户的头像
  15.         public string AvatarUrl { get; set; }
  16.         // 获胜的场数
  17.         public int WinNumber { get; set; }
  18.         // 失败的场数
  19.         public int LoseNumber { get; set; }
  20.         // 和棋的场数
  21.         public int DrawNumber { get; set; }
  22.         // 排名
  23.         public int RankNumber { get; set; }
  24.     }
  25. }
复制代码
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace Tool
  11. {
  12.     // 将参数Param转换为Target类型
  13.     public static  class TypeExtract
  14.     {
  15.         /// <summary>
  16.         /// 将对应的类型转换为我们要转换的类型
  17.         /// </summary>
  18.         /// <param name="source"></param>
  19.         /// <param name="target"></param>
  20.         public static T TransformToTargetBased<E,T>(E source,Type target,bool ignoreNull=false) where T:new()
  21.         {
  22.             // 1.获取到来源类的所有公开的属性
  23.             PropertyInfo[] sourceInfos = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
  24.             // 2.将其转换为一个Key:属性名,Value:属性值的字典
  25.             Dictionary<string, object> sourceDictionary = new Dictionary<string, object>();
  26.             foreach (PropertyInfo sourceInfo in sourceInfos)
  27.             {
  28.                 sourceDictionary[sourceInfo.Name] = sourceInfo.GetValue(source);
  29.             }
  30.             // 3.获取到我们的目标类型的所有的属性
  31.             T targetObj = new T();
  32.             PropertyInfo[] targetInfos = targetObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
  33.             // 4.将来源对象的值转载到目标对象上
  34.             foreach (PropertyInfo targetInfo in targetInfos) {
  35.                 // 5.判断是否忽略空值
  36.                 if(ignoreNull)
  37.                 {
  38.                     // 6.如果是忽略空值,则值为null的话就省略
  39.                     if(sourceDictionary[targetInfo.Name] != null)
  40.                     {
  41.                         targetInfo.SetValue(targetObj, sourceDictionary[targetInfo.Name]);
  42.                     }
  43.                     continue;
  44.                 }
  45.                 else
  46.                 {
  47.                     // 7.如果不选择忽略空值,则我们就直接将对应的值加到对应的属性上
  48.                     targetInfo.SetValue(targetObj, sourceDictionary[targetInfo.Name]);
  49.                 }
  50.             }
  51.             return targetObj;
  52.         }
  53.     }
  54. }
复制代码
最后我再写一个Api测试一下
  1. [HttpGet]
  2. public UserDTO Get() {
  3.         User user = context.Users.Where(u => u.UserId == 1).Single();
  4.         UserDTO usreDto = TypeExtract.TransformToTargetBased<User,UserDTO>(user,new UserDTO().GetType());
  5.         return usreDto;
  6. }
复制代码


呼哈,成功,这个工具类我测试过,不仅仅是基本类型可以转换,里面的属性如果是引用类型一样可以转换,如果大家有更好的方法,希望大家分享出来,谢谢!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4