一、什么是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<ProductDto>(strSql).FirstOrDefault<ProductDto>();
}
}
}

结果:

从截图中看出,返回的就是想要的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<ProductDto>(strSql).FirstOrDefault<ProductDto>(); // 方式二:使用委托进行自定义映射
string strSql2 = @" SELECT p.ProductId,p.ProductName,p.Price,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId ";
// 定义映射的委托
Func<ProductDetail, Category, ProductDto> 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<ProductDto> list = conn.Query<ProductDetail, Category, ProductDto>(strSql2, map, splitOn: splitOn).ToList<ProductDto>();
}
}
}

结果:

注意:

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<ProductDto>(strSql).FirstOrDefault<ProductDto>(); // 方式二:使用委托进行自定义映射
string strSql2 = @" SELECT p.ProductId,p.ProductName,p.Price,c.CategoryName FROM Category c INNER JOIN ProductDetail p ON c.CategoryId=p.CategoryId ";
// 定义映射的委托
//Func<ProductDetail, Category, ProductDto> 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<Category, ProductDetail, ProductDto> 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<ProductDto> list = conn.Query< Category, ProductDetail, ProductDto>(strSql2, map, splitOn: splitOn).ToList<ProductDto>();
}
}
}

结果:

轻量级ORM框架Dapper应用八:使用Dapper实现DTO的更多相关文章

  1. 轻量级ORM框架初探-Dapper与PetaPoco的基本使用

    一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库 ...

  2. .NET轻量级ORM框架Dapper入门精通

    一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架 ...

  3. 轻量级ORM框架Dapper应用一:Dapper安装

    一.Dapper简介 Dapper是一款轻量级ORM框架,为解决网站访问流量极高而产生的性能问题而构造,主要通过执行TSQL表达式而实现数据库的CQRS. 如果你在项目中遇到性能访问问题,选择Dapp ...

  4. 分享自己写的基于Dapper的轻量级ORM框架~

    1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...

  5. C# 性能优化 之 秒表 Stopwatch。 Dapper一个和petapoco差不多的轻量级ORM框架

    Sweet小马 小马同学的编程日记. C# 性能优化 之 秒表 Stopwatch. 生词解释:Diagnostics[,daɪəg'nɑstɪks] n.诊断学 using System.Diagn ...

  6. c# 轻量级ORM框架 实现(一)

    发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给 ...

  7. 轻量级ORM框架 QX_Frame.Bantina(二、框架使用方式介绍)

    轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...

  8. 轻量级ORM框架 QX_Frame.Bantina(一、框架简介)

    轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...

  9. 轻量级ORM框架——第一篇:Dapper快速学习

    我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db,而且市面上的orm框架有很多,其中有一个框架 叫做dapper,而且被称为th ...

  10. 基于轻量级ORM框架Dapper的扩展说明

    这里简单的介绍一下本人基于Dapper作的一些简单的扩展,供大家参考. 为何要使用这款框架,相信大家看到下面排名就清楚了 其实在各大网站上,我们大概都会看到这样的一个对比效果图,在超过500次poco ...

随机推荐

  1. 纯干货,Spring-data-jpa详解(转)

    本篇进行Spring-data-jpa的介绍,几乎涵盖该框架的所有方面,在日常的开发当中,基本上能满足所有需求.这里不讲解JPA和Spring-data-jpa单独使用,所有的内容都是在和Spring ...

  2. 基础001_Xilinx V7资源

    作者:桂. 时间:2018-02-08  09:37:35 链接:http://www.cnblogs.com/xingshansi/p/8430247.html 前言 本文主要是Xilinx V7系 ...

  3. unity, 删除animationClip中的position曲线

    删除clip中所有的position曲线: using UnityEngine; using System.Collections; using UnityEditor; public class r ...

  4. LVS:三种负载均衡方式比较+另三种负载均衡方式

    转:http://blog.csdn.net/u013256816/article/details/50705578 什么是LVS?   首先简单介绍一下LVS (Linux Virtual Serv ...

  5. Android:使用 DownloadManager 进行版本更新,出现 No Activity found to handle Intent 及解决办法

    项目中,进行版本更新的时候,用的是自己写的下载方案,最近看到了使用系统服务 DownloadManager 进行版本更新,自己也试试. 在下载完成以后,安装更新的时候,出现了一个 crash,抓取的 ...

  6. u3d中的坐标系

    任何子级游戏对象 (Child GameObject) 的检视器 (Inspector) 中的变换 (Transform) 值都会相对于父级 (Parent) 的变换 (Transform) 值而显示 ...

  7. Spring boot下添加filter

    https://www.cnblogs.com/OnlyCT/p/7133639.html ****************************************************** ...

  8. kkpager的改进,Ajax数据变化但是页码不变的有关问题

    kkpager的改进,Ajax数据变化但是页码不变的问题kkpager 是一个简单分页展示插件,需要依赖jquery.下载地址:http://www.oschina.net/action/projec ...

  9. visual studio如何附加到进程调试python命令

    既然是调试python脚本,那么我首先想到的是附加到进程(python.exe) 至于为什么不用F5直接启动python脚本呢,因为调用命令如下 C:> python test.py < ...

  10. postgresql相关命令

    1,打开命令窗口: 2,查看数据库用户:\du 3,列出所有数据库名:\l或者SELECT datname FROM pg_database; 4,切换某个数据库下面的某个用户下面:\c 数据库名 用 ...