计算机数据

在本文中,我们将介绍如何使用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方法进行归档。现在让我们把重点放在如何在代码中执行这些操作。

本文源自: 

本博客作者与Github上作者(cnxy)实为同一个作者。由于笔者翻译水平有限,文本中错误难免,欢迎指正!

 

查询无关实体

假设我们想从API中检索书籍和视频列表。我们可以通过两个简单的选择所有查询来实现这一点,数据库结果看起来如下: 图片 1

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

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

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

图片 2

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

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

 

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

图片 3

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

图片 4

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

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中运行,以查看行动中的结果:

图片 5

 

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

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

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

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

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

图片 6

总结:

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

 

本文翻译自:StackExchange.Dapper

原版教程源自:Dapper Tutorial

中文教程源自:中文Dapper教程.GitBook

中文教程PDF:dapper-tutorial-cn

Dapper - .Net版本的简单对象映射器

发行说明

请见 stackexchange.github.io/Dapper

组件

Nuget稳定版:

https://www.nuget.org/packages/Dapper

Visual Studio 程序包管理器控制台:

PM> Install-Package Dappe

特点

Dapper是一个NuGet库,您可以将其添加到项目中,以扩展您的IDbConnection接口。

它提供了3个使用方法:

执行一个查询并将结果映射到强类型列表

public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)

示例:

public class Dog
{
    public int? Age { get; set; }
    public Guid Id { get; set; }
    public string Name { get; set; }
    public float? Weight { get; set; }

    public int IgnoredProperty { get { return 1; } }
}

var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

Assert.Equal(1,dog.Count());
Assert.Null(dog.First().Age);
Assert.Equal(guid, dog.First().Id);

执行一个查询并将其映射到动态对象列表

public static IEnumerable<dynamic> Query (this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)

这个方法会执行SQL语句,并返回一个动态列表。

示例:

var rows = connection.Query("select 1 A, 2 B union all select 3, 4");

Assert.Equal(1, (int)rows[0].A);
Assert.Equal(2, (int)rows[0].B);
Assert.Equal(3, (int)rows[1].A);
Assert.Equal(4, (int)rows[1].B);

执行不返回结果的命令

public static int Execute(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null)

示例:

var count = connection.Execute(@"
  set nocount on
  create table #t(i int)
  set nocount off
  insert #t
  select @a a union all select @b
  set nocount on
  drop table #t", new {a=1, b=2 });
Assert.Equal(2, count);

多次执行命令

还允许使用相同的参数签名方便有效地多次执行命令(例如批量加载数据)

示例:

var count = connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
  );
Assert.Equal(3, count); // 插入3行: "1,1", "2,2" 与 "3,3"

这适用于已经实现IEnumerable接口的集合对象T。

性能

Dapper的一个关键特性是性能。 以下度量标准显示了对DB执行500个SELECT语句并将返回的数据映射到对象所需的时间。

性能测试分为3个列表:

  • 支持从数据库中提取静态类型对象框架的POCO序列化,使用原生SQL语句。
  • 支持返回动态对象列表框架的动态序列化。
  • 典型的框架用法:通常典型的框架使用与最佳使用性能明显不同,并且它不会涉及编写SQL语句。

超过500次迭代的SELECT映射性能 - POCO序列化

方法 执行时间 备注
手工编码 (使用 SqlDataReader) 47ms  
Dapper ExecuteMapperQuery 49ms  
ServiceStack.OrmLite (使用Id查询) 50ms  
PetaPoco 52ms 可以更快
BLToolkit 80ms  
SubSonic CodingHorror 107ms  
NHibernate SQL 104ms  
Linq 2 SQL ExecuteQuery 181ms  
Entity framework ExecuteStoreQuery 631ms  

超过500次迭代的SELECT映射性能 - 动态序列化

方法 执行时间 备注
Dapper ExecuteMapperQuery (动态) 48ms  
Massive 52ms  
Simple.Data 95ms  
其他新闻
  • AndroidStudio 本身就慢,启动时还自动打开上次的项目,然后如果不是自己要的项目,又得Close Project。 1、设置成Eclipse快捷键 设置成Eclipse快捷键 Settings -Keymap,在Keymaps下拉列表中选择...
    2020-01-17
  • Android 日期时间-new Date() 及其格式化、System.currentTimeMillis() Android 日期时间-new Date()的坑 Android 日期时间-Calendar 代替 new Date()仍有坑 Android日期时间-日期与字符串相互转换的坑 一、...
    2020-01-17
  • 程序在手机上调试运行成功,签名生成APK 也成功,但是在手机上安装居然失败。 android studio 升级2.3之后,签名打包需要选择Signature versions,如下图 原来签名时,Signature Versions 不能只...
    2020-01-17
友情链接

公司名称巴黎人电玩
版权所有:Copyright © 2015-2019 http://www.zhongqiangjy.com. 巴黎人电玩有限公司 版权所有

友情链接

Copyright © 2015-2019 http://www.zhongqiangjy.com. 巴黎人电玩有限公司 版权所有
公司地址http://www.zhongqiangjy.com