使用Dapper处理多个结果集和多重映射的教程
在本文中,我们将介绍如何使用DAPPER从单个数据库调用中读取数据库中的多个结果集。我们将看看我们可能希望这样做的场景,以及如何使用它的Query和QueryMultiple方法更简洁地实现这一点。 当我们谈论以数据为中心的应用程序时,可能会出现一些场景,在这些场景中我们可能希望从数据库中检索多重结果。多个结果集既可以是相关的,也可以是无关的。要做到这一点,我们不需要对数据库进行多次往返,而是可以在一次数据库调用本身中实际使用dapper检索结果,然后将结果映射到代码中的所需对象。 在我们继续并开始研究如何做到这一点之前,让我们首先试着理解在我们的应用程序中可能希望做到这一点的场景: 1、查询无关实体:所请求的实体根本不相关。 2、查询具有1至多个关系的相关实体:被请求的实体具有1对多的关系,我们需要在代码中处理多个结果集 3、查询具有1至1关系的相关实体:被请求的实体具有1-1关系,我们需要在代码中执行处理多个映射 在第一个场景中,我们有完全不相关的实体,因此基本上,我们只想执行两个独立的查询来检索数据,然后将其映射到这些实体。在第二个场景中,返回的实体与1-多相关,因此我们希望检索数据,然后将结果映射到具有1至多个关系的POCO中。最后,在第三个场景中,返回的实体是1-1,因此我们希望检索数据,然后将结果映射到具有1-1关系的POCO中。 现在让我们看看一些代码,了解如何使用Dapper来实现这一切。 所有这些都可以通过DAPPER的查询、QueryMultiple和Read方法进行归档。现在让我们把重点放在如何在代码中执行这些操作。
查询无关实体
假设我们想从API中检索书籍和视频列表。我们可以通过两个简单的选择所有查询来实现这一点,数据库结果看起来如下:
现在,为了能够从代码中执行同样的操作,我们首先需要定义我们的实体:
1 public class Book 2 { 3 public int ID { get; set; } 4 public string BookName { get; set;} 5 public string ISBN { get; set; } 6 } 7 8 public class Video 9 { 10 public int ID { get; set; } 11 public string VideoName { get; set; } 12 }
使用这些模型,让我们看看如何只使用一个数据库调用来使用DAPPER检索这些结果:
1 public IActionResult Index() 2 { 3 // define our SQL query - it contains mulitple queries seprated by ; 4 var query = "SELECT * from Books; Select * from Videos"; 5 6 // Execute the query 7 var results = dbConnection.QueryMultiple(query); 8 9 // retrieve the results into the respective models 10 var books = results.Read<Book>(); 11 var videos = results.Read<Video>(); 12 13 return Ok(new { Books = books, Videos = videos}); 14 }
现在让我们在POSTMAN中运行,以查看行动中的结果:
注意:我已经创建了一个简单的API控制器来测试这个代码,所有的DB访问代码都在里面运行。这只是为了演示目的和现实世界的应用,这样的代码根本不应该被使用。
查询具有1到多关系的查询相关实体
检索相关实体的另一个典型场景是实体之间存在一对多关系。让我们尝试使用组织和联系人的例子来可视化这一点。组织通常具有与其关联的多个联系人。如果我们想要检索一个组织,并且想要检索所有关联的联系人,我们可以利用QueryMultiple来做到这一点。这就是关系在数据库中的样子。
首先让我们检查一下如何使用SQL查询做同样的操作。
现在,如果我们必须在代码中做同样的事情,我们首先需要定义我们的实体。请注意,我们的实体也将建模一对多关系的方式,每个组织有一个联系人列表。
public class Organization {public int ID { get; set; }public string OrganizationName { get; set; }public List<contact> Contacts { get; set; } }public class Contact {public int ID { get; set; }public int OrganizationId { get; set; }public string ContactName { get; set; } } </contact>
现在让我们看一下用于检索这些相关实体的代码,并了解如何用dapper的QueryMultiple方法填充与1到多个关系相关的实体。
[HttpGet("{id}")] public IActionResult GetOrganization(int id) {// define our SQL query - it contains mulitple queries seprated by ;var query = @"SELECT* from Organizations where id = @id;Select * from Contacts where OrganizationId = @id";// Execute the queryvar results = dbConnection.QueryMultiple(query, new { @id = id });// retrieve the results into the respective modelsvar org = results.ReadSingle<Organization>();org.Contacts = results.Read<Contact>().ToList();return Ok(org); }
在上面的代码中,我们可以看到我们是如何同时执行2个查询的。我们接受了第一个查询结果并填充了我们的组织对象。第二个查询结果作为同一个组织对象的联系人集合被推送。
现在让我们在POSTMAN中运行,以查看行动中的结果:
具有1到1关系的查询相关实体
前两个场景非常简单,因为它们要求我们编写两个独立的查询,然后独立收集每个查询的结果,以便根据需要创建模型对象。
但是有1到1个关系的场景是很棘手的。从数据库的角度来看,我们可以在单个SQL查询本身中检索相关实体,但是随后我们希望将单个结果集映射到代码中的多个对象中。这可以使用在DAPPER中可用的多重映射特征来完成。让我们在一个例子的帮助下理解这一点。
注意:我们仍然可以使用与1到许多关系相同的方法来检索与1到1相关的数据,但是本节将展示如何使用单个SQL并映射结果。
让我们举一个联系和护照的例子。每个联系人只能有一个护照。让我们先想象一下这个数据库关系。
现在,让我们看看是否需要从数据库中检索联系人列表及其护照信息,我们如何用SQL实现这一点。
现在让我们看看我们的实体如何寻找联系和护照。
public class Contact {public int ID { get; set; }public int OrganizationId { get; set; }public string ContactName { get; set; }public Passport Passport { get; set; } }public class Passport {public int ID { get; set; }public int Contactid { get; set; }public string PassportNumber { get; set; } }
现在让我们看看如何从数据库中检索这些相关实体,并使用更简洁的多重映射完整地填充具有相同关系的POCOs。
[HttpGet("{id}")] public IActionResult GetContact(int id) {var query = @"Selectc.ID, c.Organizationid, c.ContactName,p.ID as PassPortId, p.ContactId, p.PassportNumberfrom Contacts c,Passports pwhere c.ID = p.ContactIDand c.id = @id";// Execute the queryvar contact = dbConnection.Query<Contact, Passport, Contact>(query, MapResults, new { @id = id }, splitOn: "PassportId");return Ok(contact); }private Contact MapResults(Contact contact, Passport passport) {contact.Passport = passport;return contact; }
在上面的代码中,我们使用的是查询方法的重载版本,它采用多个类型。传递的类型是我们要映射的每个对象的类型参数,最后一个类型参数是表示该查询将返回的对象类型的附加参数。
因此,在我们的查询中,我们希望将结果映射到类型Contact和Passsport,然后期望结果返回到类型Contact的对象中。
现在,让我们看看在查询方法中传递的实际参数。
第一个参数是SQL查询本身。
第二个参数是映射函数,它将获取结果,将它绑定到相应的类型,然后创建所需的返回类型并返回该返回类型。在我们的代码中,它采用Contact和Passport类型,并将Contact的Passport属性指定为正在传递的Passport值。一旦这样做,结果接触类型返回。
第三个参数是命令参数@ id。
最后一个参数拆分是将告诉DAPPER哪些列必须映射到下一个对象的列名。在我们的示例中,我们将此值作为PassportId传递,这意味着在找到PassportId列之前,所有列都将映射到第一种类型,即Contact,然后随后的列将被映射到下一个参数类型,即Passport。
注意:如果我们有2个以上的对象需要映射,splitOn将是一个逗号分隔的列表,其中每个列名将充当分隔符,并开始下一个对象类型的映射列。
现在让我们在POSTMAN中运行,以查看行动中的结果:
欧了,我们使用DAPPER从数据库中检索多个结果集,以避免数据库往返。
总结:
在本文中,我们讨论了如何使用dapper提供的特性在一次运行中检索多个相关或无关的实体,从而避免多次数据库往返。这是从初学者的角度写的。我希望这有一定的信息性。
转载于:https://www.cnblogs.com/shengya/p/9671932.html
使用Dapper处理多个结果集和多重映射的教程相关推荐
- Servlet的多重映射
虚拟路径 在web.xml文件中,一个<Servlet-mapping>元素 用于映射一个Servlet的对外访问路径,该路径称为虚拟路径 比如HelloWorldServlet,映射的虚 ...
- ZGC的多重映射,会不会造成 虚拟内存很多,而实际的物理内存已经不够用的情况?
ZGC的内存多重映射确实可能导致虚拟内存占用较多的情况,但并不会导致实际的物理内存不够用. 在ZGC中,内存多重映射是基于页的,每个页的大小通常为2MB,而且ZGC会动态调整映射的页的数量,以使得虚拟 ...
- YOLOV3林业病虫害数据集和数据预处理-paddle教程
林业病虫害数据集和数据预处理方法介绍 在本课程中,将使用百度与林业大学合作开发的林业病虫害防治项目中用到昆虫数据集. 读取AI识虫数据集标注信息 AI识虫数据集结构如下: 提供了2183张图片,其中训 ...
- servlet多重映射_关于多重映射问题,很奇怪
发表时间:2004-03-29 我说说我的情况吧! 我的表是多对多关联! schema如下 drop table if exists course_employee_link drop table i ...
- python多重循环break_Python教程:跳出多层循环for、while
for跳出多层循环 break_flag = False for i in range(10): print("爷爷层",i) for j in range(10): print( ...
- servlet多重映射_【简答题】请简要概述什么是Servlet的多重映射,并列出Servlet多重映射的实现方式。...
[单选题]在统计分析图中,条形图通常用于描述 ( ) A. 二元变量的观测数据 B. 某种事物在时间序列上的变化趋势 C. 具有百分比结构的分类数据 D. 离散性变量的统计事项 [判断题]3.在Exc ...
- servlet多重映射_一个
读下面我国两大河流示意图,回答下列问题:(1)黄河的①.②.③河段中,不会出现凌汛现象的是_____________.(填代码 有关长江的叙述,不正确的是()A.长江水能蕴藏量占全国的一半,但目前开发 ...
- C#的dapper使用
Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的.Dapper只有一个代码文件,完全开源,你可以放在项目里的任何 ...
- 【无标题】如何在C#中使用Dapper ORM学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
最新文章
- 处有未经处理的异常:0xC0000005 : 读取位置 0x00000000 时发生访问冲突。
- 第一行代码读书笔记1+常见错误分析
- Web Application Stress Tool(WAS)性能测试
- 【工具使用系列】关于 MATLAB 电路与系统分析,你需要知道的事
- Unable to resolve target 'android-5'
- python生成树状图_python 生成 树状结构
- ap设置 维盟660g_New丨维盟双频百兆11ac入墙AP:WAP-3018穿墙效果不一样!
- 重排列(51Nod-2513)
- python库下载安装_Windows版的各种Python库安装包下载地址与安装过程
- cnpack代码输入助手失效的解决办法
- ideapad linux s9_联想IdeaPad S9 电源管理驱动
- MyBatis Generator 代码生成器窜库问题
- sg11解密 php解密 SourceGuardian解密sg_load解密去除域名IP授权
- 使用 ESP-Prog / Jlink 进行 JTAG 调试时的常见错误及解决办法
- TCP/IP(3)——IPV6
- 关于extjs中的cls ≠ class
- 2021-05-07:set,hashmap,collisions, map 242 1 15 18
- emoji 原生表情解析成对应表情包png
- 使用Python对文件进行批量改名
- [渝粤教育] 西南科技大学 现代数字系统设计 在线考试复习资料2021版
热门文章
- ResNeXt结构(code)
- 【java】窗口控件及字符串和异常的综合应用
- 知识图谱中的关系推理
- 详细解读Youtube推荐算法
- 【Keras】完整实现‘交通标志’分类、‘票据’分类两个项目,让你掌握深度学习图像分类...
- 现在做网络推广,哪种方式最好?
- android 使用so库,Android 使用SO库
- cifar10数据集测试有多少张图_图神经网络的ImageNet?斯坦福开源百万量级OGB基准测试数据集...
- 删除virtual bridge
- 编程 ul 不能一行显示 跳到下行_史上最全的数控G代码编程详解