網站首頁 編程語言 正文
一、什么是DTO
先來看看百度百科的解釋:
數據傳輸對象(DTO)(Data Transfer Object),是一種設計模式之間傳輸數據的軟件應用系統。數據傳輸目標往往是數據訪問對象從數據庫中檢索數據。數據傳輸對象與數據交互對象或數據訪問對象之間的差異是一個以不具有任何行為除了存儲和檢索的數據(訪問和存取器)。
二、為什么需要DTO
在一個軟件系統的實現中,我們常常需要訪問數據庫,并將從數據庫中所取得的數據顯示在用戶界面上。這樣做的一個問題是:用于在用戶界面上展示的數據模型和從數據庫中取得的數據模型常常具有較大區別。在這種情況下,我們常常需要向服務端發送多個請求才能將用于在頁面中展示的數據湊齊。
三、使用Dapper實現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) { // 數據庫連接 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,將查詢的字段轉換成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 (); } } }
結果:
從截圖中看出,返回的就是想要的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) { // 數據庫連接 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,將查詢的字段轉換成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語句中根據哪個字段進行分割 string splitOn = "CategoryName"; List list = conn.Query (strSql2, map, splitOn: splitOn).ToList (); } } }
結果:
注意:
1、splitOn
splitOn表示查詢的SQL語句中按照哪個字段進行分割,splitOn的順序是從右向左的,遇到splitOn設置的字段接結束,把從右邊開始到設置的這個字段歸為同一個實體。例如:上面的例子中,splitOn設置為CategoryName,則表示從右邊開始,到CategoryName為止的所有字段都是屬于Category這個實體的,剩余的字段都是屬于ProductDetail實體的。
2、注意委托中實體類的前后順序
委托中實體類的前后順序一定要和查詢的SQL語句中字段的前后順序一致,上面的例子中先查詢的ProductDetail、后查詢的Category,那么定義委托的時候,要先寫ProductDetail,后寫Category,如果委托中實體類的順序錯了,那么不會得到映射的數據,看下面的例子:
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) { // 數據庫連接 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,將查詢的字段轉換成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語句中根據哪個字段進行分割 string splitOn = "CategoryName"; List list = conn.Query< Category, ProductDetail, ProductDto>(strSql2, map, splitOn: splitOn).ToList (); } } }
結果:
原文鏈接:https://www.cnblogs.com/dotnet261010/p/9134559.html
相關推薦
- 2022-07-16 訓練YOLOX時,出現“BrokenPipeError: [Errno 32] Broken pip
- 2023-01-08 Android?IntentFilter的匹配規則示例詳解_Android
- 2022-09-18 在while中使用cin>>a?為條件及注意事項說明_C 語言
- 2023-06-16 Golang調用FFmpeg轉換視頻流的實現_Golang
- 2023-10-10 微信授權與拒絕授權的彈窗處理
- 2022-04-21 python數據類型bytes?和?bytearray的使用與區別_python
- 2024-03-05 git的使用
- 2022-06-01 C語言?詳細分析結構體的內存對齊_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支