一、什么是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. Vue基本概念介绍及vue-cli环境搭建

    1 js中初始化一个Vue对象,传的参数就是对象属性. 挂载点.模板.实例之间的关系. var vm = new Vue({ el:"#app", template:'<di ...

  2. android check box 自定义图片

    http://blog.csdn.net/competerh_programing/article/details/7417074

  3. testbench的设计 文件读取和写入操作 源代码

    十大基本功之 testbench 1. 激励的产生 对于 testbench 而言,端口应当和被测试的 module 一一对应.端口分为 input,output 和 inout 类型产生激励信号的时 ...

  4. 使用Karma、Mocha实现vue单元测试

    Karma Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner).该工具在Vue中的主要作用是将项目运行在各种主流Web浏览器进行测试.换句话说,它是 ...

  5. NGINX宏观手记(变量|配置)

    前言 任何一个工具都有它的灵魂所在,作为一个PHP程序员,我们可能仅仅使用了它的一小部分,这篇文章让你更加了解Nginx,本章大多都是总结.翻译.整理 ,希望你可以知道nginx不仅仅是PHP的附属品 ...

  6. 浅谈hibernate的sessionFactory和session

    一.hibernate是什么? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hiber ...

  7. C++文件读写 打开方式等比较全

    要求:掌握文本文件读写的方法了解二进制文件的读写方法 C++文件流:fstream // 文件流ifstream // 输入文件流ofstream // 输出文件流 //创建一个文本文件并写入信息// ...

  8. c++ STL map 结构体

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...

  9. IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)

    名词解析: 主机字节序: 不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序.最常见的有两种 1.Little endian:低字节存高地址,高字节存低地址 2.Bi ...

  10. ubuntu 查看软件安装目录以及安装版本

    1.aptitude show 软件名 例如:aptitude show kde-runtime ****@ubuntu:~$ aptitude show kde-runtime 软件包: kde-r ...