热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用Dapper处理多个结果集与多重映射实例教程

前言对象关系映射(ORM)已经被使用了很长时间,以解决在编程过程中对象模型与数据模型在关系数据库中不匹配的问题。Dapper是由StackOverFlo

前言

对象关系映射(ORM)已经被使用了很长时间,以解决在编程过程中对象模型与数据模型在关系数据库中不匹配的问题。

Dapper是由Stack OverFlow团队开发的开源的,轻量级的ORM.相比于其他的ORM框架,Dapper速度非常快。

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中检索书籍和视频列表。我们可以通过两个简单的选择所有查询来实现这一点,数据库结果看起来如

如何使用Dapper处理多个结果集与多重映射实例教程

现在,为了能够从代码中执行同样的操作,我们首先需要定义我们的实体:

public class Book
{
 public int ID { get; set; }
 public string BookName { get; set;}
 public string ISBN { get; set; }
}

public class Video
{
 public int ID { get; set; }
 public string VideoName { get; set; }
}

使用这些模型,让我们看看如何只使用一个数据库调用来使用DAPPER检索这些结果:

public IActionResult Index()
{
 // define our SQL query - it contains mulitple queries seprated by ;
 var query = "SELECT * from Books; Select * from Videos";

 // Execute the query
 var results = dbConnection.QueryMultiple(query);

 // retrieve the results into the respective models
 var books = results.Read();
 var videos = results.Read

现在让我们在POSTMAN中运行,以查看行动中的结果:

如何使用Dapper处理多个结果集与多重映射实例教程

注意:我已经创建了一个简单的API控制器来测试这个代码,所有的DB访问代码都在里面运行。这只是为了演示目的和现实世界的应用,这样的代码根本不应该被使用。

查询具有1到多关系的查询相关实体

检索相关实体的另一个典型场景是实体之间存在一对多关系。让我们尝试使用组织和联系人的例子来可视化这一点。组织通常具有与其关联的多个联系人。如果我们想要检索一个组织,并且想要检索所有关联的联系人,我们可以利用QueryMultiple来做到这一点。这就是关系在数据库中的样子。

如何使用Dapper处理多个结果集与多重映射实例教程

首先让我们检查一下如何使用SQL查询做同样的操作。

如何使用Dapper处理多个结果集与多重映射实例教程

现在,如果我们必须在代码中做同样的事情,我们首先需要定义我们的实体。请注意,我们的实体也将建模一对多关系的方式,每个组织有一个联系人列表。

public class Organization
{
 public int ID { get; set; }
 public string OrganizationName { get; set; }

 public List Contacts { get; set; }
}

public class Contact
{
 public int ID { get; set; }
 public int OrganizationId { get; set; }
 public string ContactName { get; set; }
}

现在让我们看一下用于检索这些相关实体的代码,并了解如何用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 query
 var results = dbConnection.QueryMultiple(query, new { @id = id });

 // retrieve the results into the respective models
 var org = results.ReadSingle();
 org.COntacts= results.Read().ToList();

 return Ok(org);
}

在上面的代码中,我们可以看到我们是如何同时执行2个查询的。我们接受了第一个查询结果并填充了我们的组织对象。第二个查询结果作为同一个组织对象的联系人集合被推送。

现在让我们在POSTMAN中运行,以查看行动中的结果:

如何使用Dapper处理多个结果集与多重映射实例教程

具有1到1关系的查询相关实体

前两个场景非常简单,因为它们要求我们编写两个独立的查询,然后独立收集每个查询的结果,以便根据需要创建模型对象。

但是有1到1个关系的场景是很棘手的。从数据库的角度来看,我们可以在单个SQL查询本身中检索相关实体,但是随后我们希望将单个结果集映射到代码中的多个对象中。这可以使用在DAPPER中可用的多重映射特征来完成。让我们在一个例子的帮助下理解这一点。

注意:我们仍然可以使用与1到许多关系相同的方法来检索与1到1相关的数据,但是本节将展示如何使用单个SQL并映射结果。

让我们举一个联系和护照的例子。每个联系人只能有一个护照。让我们先想象一下这个数据库关系。

如何使用Dapper处理多个结果集与多重映射实例教程

现在,让我们看看是否需要从数据库中检索联系人列表及其护照信息,我们如何用SQL实现这一点。

如何使用Dapper处理多个结果集与多重映射实例教程

现在让我们看看我们的实体如何寻找联系和护照。

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 = @"Select
    c.ID, c.Organizationid, c.ContactName,
    p.ID as PassPortId, p.ContactId, p.PassportNumber
    from Contacts c,
    Passports p
    where c.ID = p.ContactID
    and c.id = @id";

 // Execute the query
 var cOntact= dbConnection.Query(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从数据库中检索多个结果集,以避免数据库往返。

总结:

在本文中,我们讨论了如何使用dapper提供的特性在一次运行中检索多个相关或无关的实体,从而避免多次数据库往返。这是从初学者的角度写的。我希望这有一定的信息性。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程笔记的支持。


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 软件测试工程师,需要达到什么水平才能顺利拿到 20k+ 无压力?
    前言最近看到很多应届生晒offer,稍有名气点的公司给出的价格都是一年30多W或者月薪20几k,相比之下工作几年的自己薪资确实很寒酸.根据我自己找工作经历,二线城市一般小公司招聘 ... [详细]
author-avatar
up61
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有