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

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

 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<Book>();
var videos = results.Read<Video>(); return Ok(new { Books = books, Videos = videos});
}

现在让我们在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 query
var results = dbConnection.QueryMultiple(query, new { @id = id }); // retrieve the results into the respective models
var 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 = @"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<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提供的特性在一次运行中检索多个相关或无关的实体,从而避免多次数据库往返。这是从初学者的角度写的。我希望这有一定的信息性。

使用Dapper处理多个结果集和多重映射的教程的更多相关文章

  1. Guava 教程(4):条件,多重映射和分片

    原文出处: oschina 在本系列博客的前三章,我们大概介绍了Google的Guava类库和Collections类库,作为一名Java开发人员,相信你会从使用这些类库,进而来减少在你项目中使用样板 ...

  2. Dapper简易教程(翻译自Github上StackExchange/Dapper)

    本文源自:https://github.com/cnxy/Dapper-zh-cn 本博客作者与Github上作者(cnxy)实为同一个作者.由于笔者翻译水平有限,文本中错误难免,欢迎指正! 本文翻译 ...

  3. dapper 学习

    上一篇, 提到Query<Test>查询的时候, 如果Test中包含自定义class, Dapper不会给自定义class完成映射, 而是直接给null, 其实是可以实现的, 答案就在下面 ...

  4. Dapper学习 - Dapper的基本用法(一) - 查询

    上一篇, 提到Query<Test>查询的时候, 如果Test中包含自定义class, Dapper不会给自定义class完成映射, 而是直接给null, 其实是可以实现的, 答案就在下面 ...

  5. [译]Dapper教程

    脑子里突然浮现出一个想法:尝试翻译一些技术文档.说干就干,先来翻译个最近经常查阅的Dapper教程,有兴趣的园友可以一起参与进来 dapper-tutorial-cn. 什么是Dapper Dappe ...

  6. Dapper 入门

    中文文档连接:https://www.w3cschool.cn/dapperorm/dapperorm-toj931f2.html 官网文档连接:https://dapper-tutorial.net ...

  7. Dapper原来还可以直接这样写SQL,很强大哦

    网络上对Dapper的解释是这样的: Dapper是一个简单的.NET对象映射器,在速度方面具有"King of Micro ORM"的头衔,几乎与使用原始的ADO.NET数据读取 ...

  8. 使用 Google Guava 美化你的 Java 代码

    文章转载自:http://my.oschina.net/leejun2005/blog/172328 目录:[ - ] 1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMP ...

  9. R----tidyr包介绍学习

    tidyr包:reshape2的替代者,功能更纯粹 tidyr包的应用 tidyr主要提供了一个类似Excel中数据透视表(pivot table)的功能;gather和spread函数将数据在长格式 ...

随机推荐

  1. SQLite 大小写敏感

    --转自mojianpo  http://mojianpo.iteye.com/blog/1496579 大部分数据库在进行字符串比较的时候,对大小写是不敏感的. 但是,在SQLite中,对大小写是敏 ...

  2. ExcelHelper office 导出

    要是服务器上没有装着excel 可以用c#导出excel表吗 2009-08-10 17:36 风之成 | 分类:办公软件 | 浏览2279次 租用的空间 服务器上没有装着office excel,可 ...

  3. c#做的查找文件夹内内容的小工具

    第一次写博客有点激动啊QAQ 来新单位,一直没活干,公司代码控制器太多,其中有很多文件夹,每次找一个控制器都老找不到,我又不愿意用VS的全局搜索,想着没事就做了个查找控制器的小工具.代码如下: 先添加 ...

  4. kafka自定义序列化器

    <kafka权威指南> Customer.java public class Customer { private int customId; private String custome ...

  5. java编程中'为了性能'一些尽量做到的地方

    原文地址:http://blog.csdn.NET/m13666368773/article/details/7796924 最近的机器内存又爆满了,出了新增机器内存外,还应该好好review一下我们 ...

  6. JavaSE环境Shiro的搭建及常用API

    通过shiroAPI来进行角色的管理 模拟用户是否登录: 模拟用户是否具有相应的权限:

  7. 数据分析核心包——pandas

    一.pandas简介 pandas是一个强大的Python数据分析的工具包,是基于NumPy构建的. 1.pandas的主要功能 (1)具备对其功能的数据结构DataFrame.Series (2)集 ...

  8. jq实现发送验证码倒计时60s

    setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式.方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭. setTimeout() :在指定的毫 ...

  9. bind 事件名称 命名空间

    1.通过在事件名称后面添加以点号分隔的后缀来为事件名称指派命名空间 $("#button").bind("click.editMode",function(){ ...

  10. IE浏览器下的渐变背景

    background: linear-gradient(to bottom, #000000 0%,#ffffff 100%);(标准) linear-gradient 在 ie9 以下是不支持的,所 ...