思想
DAO(Data Access Object)數(shù)據(jù)訪問對(duì)象,是我們?cè)谧鼋Y(jié)構(gòu)化數(shù)據(jù)庫訪問的時(shí)候傳輸?shù)膶?duì)象,通過這個(gè)對(duì)象我們可以與數(shù)據(jù)庫中的表建立映射關(guān)系
DTO(Data Transfer Object)是我們?cè)谂c前端進(jìn)行數(shù)據(jù)交換時(shí)傳遞的對(duì)象
為什么需要設(shè)置這這兩種對(duì)象呢?
- 為了數(shù)據(jù)安全
如果我們直接傳遞DAO的數(shù)據(jù),我們可能回把數(shù)據(jù)庫的底庫都扒光,比如一個(gè)用戶的數(shù)據(jù),包括用戶的Id、用戶的賬號(hào)、密碼等,我們直接傳遞到前端,用戶的密碼有可能被抓包軟件給獲取到,之后用戶賬號(hào)就可能回被盜用,而為了杜絕這種情況,我們從后端就直接把數(shù)據(jù)給換掉 - 除了DTO,甚至我們?cè)谀承┖蠖伺c數(shù)據(jù)庫進(jìn)行某些數(shù)據(jù)交換的時(shí)候也會(huì)設(shè)置一個(gè)中間模型,而不是直接使用DAO,因?yàn)槟承?shù)據(jù)庫表的字段過多,我們進(jìn)行業(yè)務(wù)的時(shí)候可能并用不到難么多的字段,所以回進(jìn)行一定的截?cái)?/li>
轉(zhuǎn)換思路
我們這里既然要轉(zhuǎn)換肯定是無論是基礎(chǔ)類型還是引用類型的屬性都可以轉(zhuǎn)換,所以我想到了利用反射
步驟:
- 獲取來來源對(duì)象的所有公開屬性
- 創(chuàng)建一個(gè)字典,字典的Key值為來源對(duì)象公開屬性名稱,字典的值為來源對(duì)象的公開屬性的值
- 創(chuàng)建出目標(biāo)類的對(duì)象,獲取到目標(biāo)類的所有公開屬性
- 根據(jù)目標(biāo)屬性名稱獲取到來源對(duì)象屬性的值,設(shè)置目標(biāo)屬性的值
代碼實(shí)現(xiàn)
來源類型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model.Entity
{
public class User
{
public int UserId { get; set; }
// QQ郵箱
public string QQEmail { get; set; }
// 昵稱
public string Nickname { get; set; }
// 密碼
public string Password { get; set; }
// 用戶狀態(tài) 0:表示online 1:表示離線 2:表示對(duì)戰(zhàn)中,-1:表示禁止登錄
public int Status { get; set; }
// 是否是管理員 0:不是 1:是
public bool IsAdmin { get; set; }
// 用戶的頭像
public string AvatarUrl { get; set; }
// 獲勝的場(chǎng)數(shù)
public int WinNumber { get; set; }
// 失敗的場(chǎng)數(shù)
public int LoseNumber { get; set; }
// 和棋的場(chǎng)數(shù)
public int DrawNumber { get; set; }
// 排名
public int RankNumber { get; set; }
// 創(chuàng)建時(shí)間
public DateTime CreateTime { get; set; }
// 修改時(shí)間
public DateTime UpdateTime { get; set; }
}
}
目標(biāo)類型
namespace gobangBack.DTO
{
public record UserDTO
{
public int UserId { get; set; }
// QQ郵箱
public string QQEmail { get; set; }
// 昵稱
public string Nickname { get; set; }
// 用戶狀態(tài) 0:表示online 1:表示離線 2:表示對(duì)戰(zhàn)中,-1:表示禁止登錄
public int Status { get; set; }
// 是否是管理員 0:不是 1:是
public bool IsAdmin { get; set; }
// 用戶的頭像
public string AvatarUrl { get; set; }
// 獲勝的場(chǎng)數(shù)
public int WinNumber { get; set; }
// 失敗的場(chǎng)數(shù)
public int LoseNumber { get; set; }
// 和棋的場(chǎng)數(shù)
public int DrawNumber { get; set; }
// 排名
public int RankNumber { get; set; }
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Tool
{
// 將參數(shù)Param轉(zhuǎn)換為Target類型
public static class TypeExtract
{
/// <summary>
/// 將對(duì)應(yīng)的類型轉(zhuǎn)換為我們要轉(zhuǎn)換的類型
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
public static T TransformToTargetBased<E,T>(E source,Type target,bool ignoreNull=false) where T:new()
{
// 1.獲取到來源類的所有公開的屬性
PropertyInfo[] sourceInfos = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// 2.將其轉(zhuǎn)換為一個(gè)Key:屬性名,Value:屬性值的字典
Dictionary<string, object> sourceDictionary = new Dictionary<string, object>();
foreach (PropertyInfo sourceInfo in sourceInfos)
{
sourceDictionary[sourceInfo.Name] = sourceInfo.GetValue(source);
}
// 3.獲取到我們的目標(biāo)類型的所有的屬性
T targetObj = new T();
PropertyInfo[] targetInfos = targetObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// 4.將來源對(duì)象的值轉(zhuǎn)載到目標(biāo)對(duì)象上
foreach (PropertyInfo targetInfo in targetInfos) {
// 5.判斷是否忽略空值
if(ignoreNull)
{
// 6.如果是忽略空值,則值為null的話就省略
if(sourceDictionary[targetInfo.Name] != null)
{
targetInfo.SetValue(targetObj, sourceDictionary[targetInfo.Name]);
}
continue;
}
else
{
// 7.1.首先判斷目標(biāo)的類屬性名是否在我們的字典中有,如果有才賦值
if(sourceDictionary.ContainsKey(targetInfo.Name))
targetInfo.SetValue(targetObj, sourceDictionary[targetInfo.Name]);
}
}
return targetObj;
}
}
}
最后我再寫一個(gè)Api測(cè)試一下
[HttpGet]
public UserDTO Get() {
User user = context.Users.Where(u => u.UserId == 1).Single();
UserDTO usreDto = TypeExtract.TransformToTargetBased<User,UserDTO>(user,new UserDTO().GetType());
return usreDto;
}
文章來源:http://www.zghlxwxcb.cn/news/detail-746189.html
呼哈,成功,這個(gè)工具類我測(cè)試過,不僅僅是基本類型可以轉(zhuǎn)換,里面的屬性如果是引用類型一樣可以轉(zhuǎn)換,如果大家有更好的方法,希望大家分享出來,謝謝!文章來源地址http://www.zghlxwxcb.cn/news/detail-746189.html
到了這里,關(guān)于C# DAO轉(zhuǎn)換為DTO工具類的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!