網(wǎng)站首頁 編程語言 正文
一、什么是DTO
先來看看百度百科的解釋:
數(shù)據(jù)傳輸對象(DTO)(Data Transfer Object),是一種設(shè)計模式之間傳輸數(shù)據(jù)的軟件應用系統(tǒng)。數(shù)據(jù)傳輸目標往往是數(shù)據(jù)訪問對象從數(shù)據(jù)庫中檢索數(shù)據(jù)。數(shù)據(jù)傳輸對象與數(shù)據(jù)交互對象或數(shù)據(jù)訪問對象之間的差異是一個以不具有任何行為除了存儲和檢索的數(shù)據(jù)(訪問和存取器)。
二、為什么需要DTO
在一個軟件系統(tǒng)的實現(xiàn)中,我們常常需要訪問數(shù)據(jù)庫,并將從數(shù)據(jù)庫中所取得的數(shù)據(jù)顯示在用戶界面上。這樣做的一個問題是:用于在用戶界面上展示的數(shù)據(jù)模型和從數(shù)據(jù)庫中取得的數(shù)據(jù)模型常常具有較大區(qū)別。在這種情況下,我們常常需要向服務端發(fā)送多個請求才能將用于在頁面中展示的數(shù)據(jù)湊齊。
三、使用Dapper實現(xiàn)DTO
使用Dapper可以直接返回DTO類型,包括兩種方式:
新建Category、ProductDetail和ProductDTO實體類:
Category實體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DapperConvertDto { public class Category { public int CategoryId { get; set; } public string CategoryName { get; set; } } }
ProductDetail實體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DapperConvertDto { public class ProductDetail { public int ProductId { get; set; } public string ProductName { get; set; } public double Price { get; set; } public int CategoryId { get; set; } } }
ProductDTO實體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DapperConvertDto { public class ProductDto { public int ProductId { get; set; } public string ProductName { get; set; } public double ProductPrice { get; set; } public string CategoryName { get; set; } } }
ProductDTO實體類中的ProductPrice對應ProductDetail表的Price,CategoryName對應Category表的CategoryName。
方式一:直接在SQL語句中使用as
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; using Dapper; namespace DapperConvertDto { class Program { static void Main(string[] args) { // 數(shù)據(jù)庫連接 string strCon = @"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=1qaz@WSX;Data Source=127.0.0.1;Failover Partner=127.0.0.1;Application Name=TransForCCT"; SqlConnection conn = new SqlConnection(strCon); // 方式一:直接在SQL語句中使用as,將查詢的字段轉(zhuǎn)換成DTO類型的屬性 string strSql = @" SELECT p.ProductId,p.ProductName,p.Price AS ProductPrice,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId "; ProductDto product = conn.Query(strSql).FirstOrDefault (); } } }
結(jié)果:
從截圖中看出,返回的就是想要的DTO類型。
方式二:使用委托的方式進行映射,分別把Category和ProductDetail實體類里的屬性,映射成ProductDTO類型的屬性:
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; using Dapper; namespace DapperConvertDto { class Program { static void Main(string[] args) { // 數(shù)據(jù)庫連接 string strCon = @"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=1qaz@WSX;Data Source=127.0.0.1;Failover Partner=127.0.0.1;Application Name=TransForCCT"; SqlConnection conn = new SqlConnection(strCon); // 方式一:直接在SQL語句中使用as,將查詢的字段轉(zhuǎn)換成DTO類型的屬性 string strSql = @" SELECT p.ProductId,p.ProductName,p.Price AS ProductPrice,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId "; ProductDto product = conn.Query(strSql).FirstOrDefault (); // 方式二:使用委托進行自定義映射 string strSql2 = @" SELECT p.ProductId,p.ProductName,p.Price,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId "; // 定義映射的委托 Func map = (p, c) => { ProductDto dto = new ProductDto(); dto.ProductId = p.ProductId; dto.ProductName = p.ProductName; dto.ProductPrice = p.Price; dto.CategoryName = c.CategoryName; return dto; }; // splitOn表示查詢的SQL語句中根據(jù)哪個字段進行分割 string splitOn = "CategoryName"; List list = conn.Query (strSql2, map, splitOn: splitOn).ToList (); } } }
結(jié)果:
注意:
1、splitOn
splitOn表示查詢的SQL語句中按照哪個字段進行分割,splitOn的順序是從右向左的,遇到splitOn設(shè)置的字段接結(jié)束,把從右邊開始到設(shè)置的這個字段歸為同一個實體。例如:上面的例子中,splitOn設(shè)置為CategoryName,則表示從右邊開始,到CategoryName為止的所有字段都是屬于Category這個實體的,剩余的字段都是屬于ProductDetail實體的。
2、注意委托中實體類的前后順序
委托中實體類的前后順序一定要和查詢的SQL語句中字段的前后順序一致,上面的例子中先查詢的ProductDetail、后查詢的Category,那么定義委托的時候,要先寫ProductDetail,后寫Category,如果委托中實體類的順序錯了,那么不會得到映射的數(shù)據(jù),看下面的例子:
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; using Dapper; namespace DapperConvertDto { class Program { static void Main(string[] args) { // 數(shù)據(jù)庫連接 string strCon = @"Initial Catalog=StudentSystem; Integrated Security=False;User Id=sa;Password=1qaz@WSX;Data Source=127.0.0.1;Failover Partner=127.0.0.1;Application Name=TransForCCT"; SqlConnection conn = new SqlConnection(strCon); // 方式一:直接在SQL語句中使用as,將查詢的字段轉(zhuǎn)換成DTO類型的屬性 string strSql = @" SELECT p.ProductId,p.ProductName,p.Price AS ProductPrice,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId "; ProductDto product = conn.Query(strSql).FirstOrDefault (); // 方式二:使用委托進行自定義映射 string strSql2 = @" SELECT p.ProductId,p.ProductName,p.Price,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId "; // 定義映射的委托 //Func map = (p, c) => //{ // ProductDto dto = new ProductDto(); // dto.ProductId = p.ProductId; // dto.ProductName = p.ProductName; // dto.ProductPrice = p.Price; // dto.CategoryName = c.CategoryName; // return dto; //}; // 錯誤的委托 Func map = (c,p) => { ProductDto dto = new ProductDto(); dto.ProductId = p.ProductId; dto.ProductName = p.ProductName; dto.ProductPrice = p.Price; dto.CategoryName = c.CategoryName; return dto; }; // splitOn表示查詢的SQL語句中根據(jù)哪個字段進行分割 string splitOn = "CategoryName"; List list = conn.Query< Category, ProductDetail, ProductDto>(strSql2, map, splitOn: splitOn).ToList (); } } }
結(jié)果:
原文鏈接:https://www.cnblogs.com/dotnet261010/p/9134559.html
相關(guān)推薦
- 2023-03-20 C#?獲取XML文件內(nèi)容的多種方式總結(jié)_C#教程
- 2022-05-03 基于Python制作一款屏幕顏色提取器_python
- 2023-03-22 gin正確多次讀取http?request?body內(nèi)容實現(xiàn)詳解_Golang
- 2023-04-18 獲取Android簽名MD5的方式實例詳解_Android
- 2022-01-04 微信小程序內(nèi)部A頁面向內(nèi)嵌H5頁面跳轉(zhuǎn),并且傳參
- 2022-08-22 Pycharm報錯Non-zero?exit?code?(2)的完美解決方案_python
- 2022-06-29 在Oracle中使用正則表達式_oracle
- 2022-10-02 基于useImperativeHandle的使用解析_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支