威尼斯人线上娱乐

Dapper简易教程,环境下二个回顾对象映射的框架

5 4月 , 2019  

本文源自: 

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

 

特性


Dapper
是多少个单身的文书,可以放进你的品种中用来扩展你的IDbConnection接口.

它提供了多个臂膀:

本文内容

  • 特点
  • 性能
  • 参数化的查询
  • List 支持
  • 缓存和非缓存的 readers
  • 多个映射
  • 多少个结实
  • 仓储进程
  • Ansi Strings 和 varchar
  • 界定和注意事项
  • Dapper 能运作在自家的 db 提供者上吧?
  • 有例子的欧洲经济共同体例子列表吗?
  • 什么人在动用 Dapper?
  • 参考

跳槽了,新公司的数额库层,准确地说,数据库层和持久层使用
Dapper,那东西确实很有益于~个人觉得这种方便性体今后三点:

  1. 能很有益于地进行数据库 DML 和 DLL 操作。比如,当您执行二个带参数的 SQL
    时,SQL
    中的变量能与你传递给它的实体或匿名对象中的属性,自定相配。而作者辈清楚,带参数的
    SQL,能增长数据库执行 SQL 的频率;
  2. 能很方便地将数据库检索结果映射为面向对象的目标。从数据库中的检索结果,平常是张二维表,如
    DataTable,而应用程序中是实体类,以及实体类的聚众,那么 Dapper
    能够将 DataTable 自动地照耀成为实体类的成团;
  3. 能很便宜地书写 SQL 语句。比如,写七个 SQL,用分号分隔。

正文内容

  • 特点
  • 性能
  • 参数化的询问
  • List 支持
  • 缓存和非缓存的 readers
  • 多个映射
  • 七个结实
  • 积存进程
  • Ansi Strings 和 varchar
  • 范围和注意事项
  • Dapper 能运行在本身的 db 提供者上呢?
  • 有例子的全体例子列表吗?
  • 哪个人在行使 Dapper?
  • 参考

跳槽了,新公司的数目库层,准确地说,数据库层和持久层使用
Dapper,那东西确实很便宜~个人认为那种方便性呈现在三点:

  1. 能很有益于地实践数据库 DML 和 DLL 操作。比如,当你执行一个带参数的 SQL
    时,SQL
    中的变量能与您传递给它的实业或匿名对象中的属性,自定相称。而我们知晓,带参数的
    SQL,能增高数据库执行 SQL 的频率;
  2. 能很便利地将数据库检索结果映射为面向对象的对象。从数据库中的检索结果,平日是张②维表,如
    DataTable,而应用程序中是实体类,以及实体类的集合,那么 Dapper
    能够将 DataTable 自动地照耀成为实体类的聚合;
  3. 能很方便地挥毫 SQL 语句。比如,写四个 SQL,用分号分隔。

本文翻译自:StackExchange.Dapper

施行三个询问,并将结果映射到贰个强类型集合中


在意:全数增添方法固然连接已经打开,假如老是关闭,他们将会退步。

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 });dog.Count()    .IsEqualTo(1);dog.First().Age    .IsNull();dog.First().Id    .IsEqualTo;

下载 Demo

下载 Demo

原版教程源自:Dapper Tutorial

实行1个询问,并将结果映射到三个动态类型集合中


该方法将实施SQL和重临叁个动态集合。

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

选拔例子:

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

(该下载包罗 Dapper 项目,项目中有 Dapper 的测试示例和总体性测试例子)

(该下载包涵 Dapper 项目,项目中有 Dapper 的测试示例和质量测试例子)

普通话教程源自:中文Dapper教程.GitBook

执行3个指令,不回来结果


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

运用例子:

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

(Dapper 的言传身教使用 SQLServer 数据库,小编个人的演示是 MySQL)

(Dapper 的以身作则使用 SQLServer 数据库,小编个人的言传身教是 MySQL)

华语教程PDF:dapper-tutorial-cn

反复实行2个限令


平等的占位符允许您方便实用的频仍执行三个命令.

利用例子:

connection.Execute(@"insert MyTable(colA, colB) values ",    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }  ).IsEqualTo(3); // 3 行 被插入: "1,1", "2,2" and "3,3"

特点


Dapper简易教程,环境下二个回顾对象映射的框架。Dapper 唯有1个文书,你能够把它拖到你的品类中,来扩充你的
IDbConnection 接口。

它提供了叁上边的救助:

特点


Dapper 唯有一个文书,你能够把它拖到你的档次中,来扩大你的
IDbConnection 接口。

它提供了三位置的帮手:

Dapper – .Net版本的简易对象映射器

性能


Dapper的3个第1个性是性质。以下指标呈现对数据库执行500次SELECT语句并再次回到数据映射到指标,必要多久。

质量测试分为多个表格:

  • POCO种类化框架帮衬从数据库到静态类型化对象,通过使用原有的SQL。
  • 动态连串化框架辅助回到动态目的的列表。
  • 卓绝的框架使用。平日典型框架使用区别于最棒的使用质量明智。经常它不会提到编写制定SQL。

进行二个查询,并把结果映射到三个强类型 list

留意:全数的扩充方法都固然数据库连接已开拓,假诺关闭连接,它们将破产。

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 });

 

dog.Count()

    .IsEqualTo(1);

 

dog.First().Age

    .IsNull();

 

dog.First().Id

    .IsEqualTo(guid);

实行三个询问,并把结果映射到3个强类型 list

注意:全部的扩张方法都借使数据库连接已打开,倘使关闭连接,它们将战败。

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 });

 

dog.Count()

    .IsEqualTo;

 

dog.First().Age

    .IsNull();

 

dog.First().Id

    .IsEqualTo;

批零表明

请见 stackexchange.github.io/Dapper

500次查询映射的属性-POCO类别化

Method

Duration

Remarks

Hand coded (using aSqlDataReader)

47ms

Can be faster

DapperExecuteMapperQuery

49ms

ServiceStack.OrmLite(QueryById)

50ms

PetaPoco

52ms

BLToolkit

80ms

SubSonic CodingHorror

107ms

NHibernate SQL

104ms

Linq 2 SQLExecuteQuery

181ms

Entity frameworkExecuteStoreQuery

631ms

施行一个查询,并把结果映射到二个动态 object 的 list

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

该方式将执行 SQL,并赶回三个动态 list,即 var 变量。

用法:

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

 

((int)rows[0].A)

   .IsEqualTo(1);

 

((int)rows[0].B)

   .IsEqualTo(2);

 

((int)rows[1].A)

   .IsEqualTo(3);

 

((int)rows[1].B)

    .IsEqualTo(4);

rows[0] 这种访问情势会出错,不知道示例是怎么给的~

实践一个查询,并把结果映射到四个动态 object 的 list

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

该方法将执行 SQL,并赶回一个动态 list,即 var 变量。

用法:

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

 

((int)rows[0].A)

   .IsEqualTo;

 

((int)rows[0].B)

   .IsEqualTo;

 

((int)rows[1].A)

   .IsEqualTo;

 

((int)rows[1].B)

    .IsEqualTo;

rows[0] 那种访问格局会出错,不知晓示例是怎么给的~

组件

Nuget稳定版:

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

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

PM> Install-Package Dappe

特点

Dapper是一个NuGet库,您能够将其添加到项目中,以增添您的IDbConnection接口。

它提供了一个使用方法:

500次查询映射的习性-动态类型类别化

Method

Duration

Remarks

DapperExecuteMapperQuery

48ms

Massive

52ms

Simple.Data

施行二个不回来结果的 Command

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

用法:

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 })

   .IsEqualTo(2);

实践三个不回来结果的 Command

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

用法:

connection.Execute(@"

  set nocount on 

  create table #t 

  set nocount off 

  insert #t 

  select @a a union all select @b 

  set nocount on 

  drop table #t", new {a=1, b=2 })

   .IsEqualTo;

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

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);

500次询问映射的性质-经典框架使用

Method Duration Remarks
Linq 2 SQL CompiledQuery 81ms Not super typical involves complex code
NHibernate HQL 118ms
Linq 2 SQL 559ms
Entity framework 859ms
SubSonic ActiveRecord.SingleOrDefault 3619ms

反复推行3个 Command


同样的签字也得以让您方便飞快地对一个命令执行数次,例如批量加载数据(bulk-load
data)。

用法:

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 } }

  ).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"

对任何类型达成 TIEnumerable 的参数都得以实施。

1再实行一个 Command


同样的签名也能够让你方便高效地对2个指令执行多次,例如批量加载数据(bulk-load
data)。

用法:

connection.Execute(@"insert MyTable(colA, colB) values ",

    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }

  ).IsEqualTo; // 3 rows inserted: "1,1", "2,2" and "3,3"

对别的项目实现 TIEnumerable 的参数都得以执行。

推行二个查询并将其映射到动态指标列表

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

本条方法会执行SQL语句,并重回1个动态列表。

示例:

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);

参数化查询


参数字传送递匿名类。那允许你命名参数简单和使您能够简单剪切和粘贴SQL代码片段在查询分析器和平运动作它们。

new {A = 1, B = "b"} // A 会被映射出参数 @A, B 对应 @B 

性能


Dapper 的最主要特色是性质。以下数据突显对二个数据库执行 SELECT 出 500
条,并把数量映射到对象中须要多久。

性格测试分为多个地方:

  • POCO 连串化框架,协助从数据库获得静态类型的目的。使用原来的 SQL。
  • 动态连串化框架,支持回到对象的动态列表。
  • 优良的框架用法。往往不会涉及编写制定 SQL。

性能


Dapper 的严重性特点是性质。以下数据展现对3个数据库执行 SELECT 出 500
条,并把数量映射到目的中需求多久。

本性测试分为四个方面:

  • POCO 种类化框架,辅助从数据库得到静态类型的对象。使用原来的 SQL。
  • 动态系列化框架,帮忙回到对象的动态列表。
  • 独立的框架用法。往往不会波及编写制定 SQL。

实践不回去结果的下令

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);

集结参数的支撑


Dapper允许您通过IEnumerable,自动化您的查询参数.

应用例子:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 });

将会被解析成这么:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

Performance of SELECT mapping over 500 iterations – POCO 序列化

方法

持续时间(毫秒)

备注

Hand coded (using a SqlDataReader)

47

Can be faster

Dapper ExecuteMapperQuery

49

同上

ServiceStack.OrmLite (QueryById)

50

同上

PetaPoco 

52

同上

BLToolkit

80

同上

SubSonic CodingHorror

107

同上

NHibernate SQL

104

同上

Linq 2 SQL ExecuteQuery

181

同上

Entity framework ExecuteStoreQuery

631

同上

Performance of SELECT mapping over 500 iterations – POCO 序列化

方法

持续时间

备注

Hand coded (using a SqlDataReader)

47

Can be faster

Dapper ExecuteMapperQuery

49

同上

ServiceStack.OrmLite (QueryById)

50

同上

PetaPoco 

52

同上

BLToolkit

80

同上

SubSonic CodingHorror

107

同上

NHibernate SQL

104

同上

Linq 2 SQL ExecuteQuery

181

同上

Entity framework ExecuteStoreQuery

631

同上

反复执行命令

还同意采纳同一的参数签名方便实用地一再执行命令(例如批量加载数据)

示例:

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的默许行为是执行sql和缓冲整个reader在回去。那是一级的在半数以上意况下,因为它最大限度地缩减共享锁在数据库和减弱了数据库在网络上的时光。

而是当执行查询您或然须要减弱内部存款和储蓄器占用并基于必要只加载对象。

Performance of SELECT mapping over 500 iterations – dynamic 序列化

方法

持续时间(毫秒)

备注

Dapper ExecuteMapperQuery (dynamic)

48

 

Massive

52

 

Simple.Data

95

 

Performance of SELECT mapping over 500 iterations – dynamic 序列化

方法

持续时间

备注

Dapper ExecuteMapperQuery

48

 

Massive

52

 

Simple.Data

95

 

性能

Dapper的3个要害个性是性质。
以下度量圭表展现了对DB执行500个SELECT讲话并将回到的数量映射到对象所需的年华。

质量测试分为三个列表:

  • 支撑从数据库中领到静态类型对象框架的POCO种类化,使用原生SQL语句。
  • 援救回到动态指标列表框架的动态类别化。
  • 一级的框架用法:常常典型的框架使用与超级使用质量分明例外,并且它不会波及编制SQL语句。

多少个映射


Dapper允许单个记录映射到多个指标。那是三个重中之重个性,即使你想幸免非亲非故的查询和期盼加载关联的对象。

选择例子:

var sql = @"select * from #Posts p left join #Users u on u.Id = p.OwnerId Order by p.Id";var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});//泛型的最后一个参数是要返回的类型var post = data.First();post.Content.IsEqualTo("Sams Post1");post.Id.IsEqualTo(1);post.Owner.Name.IsEqualTo("Sam");post.Owner.Id.IsEqualTo(99);

要害注意Dapper假诺您的Id列命名称叫“Id”或“Id”,假若您的主键不是,或你想分割宽行的“Id”,使用可选的“splitOn”参数。

Performance of SELECT mapping over 500 iterations – 典型用法

方法

持续时间(毫秒)

备注

Linq 2 SQL CompiledQuery

81

Not super typical involves complex code

NHibernate HQL

118

 

Linq 2 SQL

559

 

Entity framework

859

 

SubSonic ActiveRecord.SingleOrDefault

3619

 

Performance of SELECT mapping over 500 iterations – 典型用法

方法

持续时间

备注

Linq 2 SQL CompiledQuery

81

Not super typical involves complex code

NHibernate HQL

118

 

Linq 2 SQL

559

 

Entity framework

859

 

SubSonic ActiveRecord.SingleOrDefault

3619

 

超过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  

四个结实


Dapper允许您处理八个结实在叁个询问中.

例子:

var sql = @"select * from Customers where CustomerId = @idselect * from Orders where CustomerId = @idselect * from Returns where CustomerId = @id";using (var multi = connection.QueryMultiple(sql, new {id=selectedId})){   var customer = multi.Read<Customer>().Single();   var orders = multi.Read<Order>().ToList();   var returns = multi.Read<Return>().ToList();   ...} 

参数化的询问


参数能够用作匿名类来传递。那使你能够轻松地给命名参数,只要不难地撩拨和粘贴
SQL 片断,并在查询分析器中进行即可。

new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B 

参数化的询问


参数能够看做匿名类来传递。那使你能够轻松地给命名参数,只要简单地划分和粘贴
SQL 片断,并在查询分析器中推行即可。

new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B 

超越500次迭代的SELECT映射品质 – 动态连串化

方法 执行时间 备注
Dapper ExecuteMapperQuery (动态) 48ms  
Massive 52ms  
Simple.Data 95ms  

积存进度


Dapper完全支持存款和储蓄进程

var user = cnn.Query<User>("spGetUser", new {Id = 1},         commandType: CommandType.StoredProcedure).SingleOrDefault();

一旦您想做的更卓越你能够那样:

var p = new DynamicParameters();p.Add("@a", 11);p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); int b = p.Get<int>("@b");int c = p.Get<int>("@c"); 

List 支持


Dapper 运转让你传递 IEnumerable,自动地参数化的查询。

例如下边 SQL 的 in 查询:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 });

将被翻译为:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

List 支持


Dapper 运维让你传递 IEnumerable,自动地参数化的查询。

比如上边 SQL 的 in 查询:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 });

将被翻译为:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

超越500次迭代的SELECT映射质量 – 典型用法

方法 执行时间 备注
Linq 2 SQL CompiledQuery 81ms 非典型的且不涉及复杂的代码
NHibernate HQL 118ms  
Linq 2 SQL 559ms  
Entity framework 859ms  
SubSonic ActiveRecord.SingleOrDefault 3619ms  

属性基准测试音信 点击那里.

能够专擅提交包罗其余OGL450M的补丁 –
运维规范测试时,请确定保障在Release中编写翻译,且不可能附加调节和测试器 (Ctrl+F五).

要么,你能够采纳Frans
Bouma的RawDataAccessBencher或OrmBenchmark测试套件作为测试工具使用。

Ansi字符串和varchar


Dapper协助varchar
params,假设您是叁个varchar列上执行多少个where子句使用参数一定要由此它以那种措施:

Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在Sql Server上第一,查询时使用unicode
unicode和ansi当查询非unicode的时候。

缓存和非缓存的 readers


Dapper 的暗许动作是实施 SQL 并在回来时缓冲整个
reader。在超越百分之五十景况下,那是脍炙人口的,因为它能最大限度地减小数据库中的共享锁,以及收缩数据库的网络时间。

只是,在举办庞大查询时,你恐怕为了削减内部存款和储蓄器的占据,只加载供给的目的。要马到成功这一点,通过缓冲到查询办法中。

/// <summary>

/// NonBuffered

/// 将会抛出异常,Invalid attempt to Read when reader is closed.

/// </summary>

public static void TestBasicStringUsageAsyncNonBuffered()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.None));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

 

/// <summary>

/// Buffered

/// 不会抛出异常

/// </summary>

public static void TestBasicStringUsageAsyncBuffered()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Buffered));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

/// <summary>

/// Pipelined

/// 将会抛出异常,Invalid attempt to Read when reader is closed.

/// </summary>

public static void TestBasicStringUsageAsyncPipelined()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Pipelined));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

缓存和非缓存的 readers


Dapper 的暗许动作是履行 SQL 并在回来时缓冲整个
reader。在大多数境况下,那是理想的,因为它能最大限度地缩小数据库中的共享锁,以及收缩数据库的互连网时间。

可是,在实施庞大查询时,你可能为了削减内部存款和储蓄器的占据,只加载供给的靶子。要完毕那一点,通过缓冲到查询办法中。

/// <summary>

/// NonBuffered

/// 将会抛出异常,Invalid attempt to Read when reader is closed.

/// </summary>

public static void TestBasicStringUsageAsyncNonBuffered()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.None));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

 

/// <summary>

/// Buffered

/// 不会抛出异常

/// </summary>

public static void TestBasicStringUsageAsyncBuffered()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Buffered));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

/// <summary>

/// Pipelined

/// 将会抛出异常,Invalid attempt to Read when reader is closed.

/// </summary>

public static void TestBasicStringUsageAsyncPipelined()

{

    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Pipelined));

    var arr = query.Result.ToArray();

    arr.IsSequenceEqualTo(new[] { "abc", "def" });

}

参数化查询

能够匿名类型作为参数举行传递,那能够轻松地命名这几个参数名称,且能够在数据库平台的查询分析器中总结地利用剪切、粘贴SQL语句并运维。

new {A = 1, B = "b"} // A映射到参数@A,B映射到参数@B

限定和警示


Dapper缓存消息每种查询在它运转时,那使它十分的快落到实处目的和工艺参数。当前的落到实处在ConcurrentDictionary最终对象缓存这几个音信。它存款和储蓄的目的不会被刷新。尽管您是动态生成SQL字符串不利用参数有十分的大希望你将境遇内部存储器难题。大家得以把词典转换为2个LRU缓存。

几个映射


Dapper
允许你把单行映射到五个对象。假使你想防止额外的询问和加载关联,那么那个作用就很重大了。

例如:

var sql = 

@"select * from #Posts p 

left join #Users u on u.Id = p.OwnerId 

Order by p.Id";

 

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});

var post = data.First();

 

post.Content.IsEqualTo("Sams Post1");

post.Id.IsEqualTo(1);

post.Owner.Name.IsEqualTo("Sam");

post.Owner.Id.IsEqualTo(99);

唤醒:Dapper 假定你的 ID
列被命名称为“ID”或“id”,假若您的主键是不一致的,可能你想在点上拆分宽行点,而不是“ID”,能够选拔可选的’splitOn’参数。

三个映射


Dapper
允许你把单行映射到四个目的。如若您想避免额外的查询和加载关联,那么那些功能就很重大了。

例如:

var sql = 

@"select * from #Posts p 

left join #Users u on u.Id = p.OwnerId 

Order by p.Id";

 

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});

var post = data.First();

 

post.Content.IsEqualTo("Sams Post1");

post.Id.IsEqualTo;

post.Owner.Name.IsEqualTo("Sam");

post.Owner.Id.IsEqualTo;

晋升:Dapper 假定你的 ID
列被取名称为“ID”或“id”,要是你的主键是差别的,恐怕您想在点上拆分宽行点,而不是“ID”,能够动用可选的’splitOn’参数。

列表辅助

Dapper允许将IEnumerable<int>作为传递参数,并能够自动地参数化查询

例子:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 } });

如军长被转换到:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

本人能在自家的数据库中采纳啊?


Dapper未有DB具体的贯彻细节,它在具有工作。净ADO提供者includingSQLite、SQL
CE、火鸟、Oracle、MySQL、PostgreSQL和SQL服务器。

三个结果


Dapper 允许你在三回询问中处理多个结实的集结。

例如:

var sql = 

@"

select * from Customers where CustomerId = @id

select * from Orders where CustomerId = @id

select * from Returns where CustomerId = @id";

 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))

{

   var customer = multi.Read<Customer>().Single();

   var orders = multi.Read<Order>().ToList();

   var returns = multi.Read<Return>().ToList();

   ...

} 

七个结实


Dapper 允许你在贰次查询中拍卖多少个结果的集合。

例如:

var sql = 

@"

select * from Customers where CustomerId = @id

select * from Orders where CustomerId = @id

select * from Returns where CustomerId = @id";

 

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))

{

   var customer = multi.Read<Customer>().Single();

   var orders = multi.Read<Order>().ToList();

   var returns = multi.Read<Return>().ToList();

   ...

} 

文字代替

Dapper援救布尔与数字类型的文字代替。

connection.Query("select * from User where UserId = {=Id}", new {Id = 1}));

文字替换不作为参数发送;
更加好的安插和过滤索引用法将被允许,但平常应严峻在测试后接纳。
当注入的值实际上是固定值(例如,特定于查询的“种类ID”,“状态代码”或“区域”)时,此功用特别有用。
当你在思维文字live数据时,也有望想到also并测试特定于提供程序的查询提醒,如带有常规参数的OPTIMIZE FOR UNKNOWN

储存进度


Dapper 完全扶助存款和储蓄进度:

var user = cnn.Query<User>("spGetUser", new {Id = 1}, 

        commandType: CommandType.StoredProcedure).First();}}}

要是你想要越来越灵敏的操作,能够这么做:

var p = new DynamicParameters();

p.Add("@a", 11);

p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);

p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

 

cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 

 

int b = p.Get<int>("@b");

int c = p.Get<int>("@c"); 

Ansi Strings 和 varchar


Dapper 援救 varchar 参数,若是你在2个 varchar 列上推行一个 where
语句,确认保障下边方式传送参数:

Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在 SQL Server 上,当查问非 Unicode 时,查询 Unicode 和 ANSI 时索要运用
Unicode。

存款和储蓄过程


Dapper 完全支持存储进度:

var user = cnn.Query<User>("spGetUser", new {Id = 1}, 

        commandType: CommandType.StoredProcedure).First();}}}

只要您想要越来越灵敏的操作,能够这么做:

var p = new DynamicParameters();

p.Add("@a", 11);

p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);

p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

 

cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 

 

int b = p.Get<int>("@b");

int c = p.Get<int>("@c"); 

Ansi Strings 和 varchar


Dapper 协助 varchar 参数,假诺您在三个 varchar 列上实施3个 where
语句,确认保证上边格局传递参数:

Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在 SQL Server 上,当查问非 Unicode 时,查询 Unicode 和 ANSI 时索要接纳Unicode。

缓冲与未缓冲阅读器

Dapper的暗许行为是实践SQL并在回来时缓冲整个阅读器。
在大多数动静下,那是好好的,因为它最小化了数据库中的共享锁并缩减了数据库互连网时间。

不过,在实践大气询问时,可能供给最小化内部存款和储蓄器占用并仅依照须要加载对象。
为此,将buffered:false传递给Query方法。

界定和注意事项


对此 Dapper
执行的各类查询的缓存信息,使得它亦可急忙地物化对象和处理参数。当前的贯彻把新闻缓存在一个ConcurrentDictionary 对象中。它存款和储蓄的靶子永远不会被刷新。假诺你转移的
SQL 字符串未有应用参数,那么恐怕会出现命中内部存款和储蓄器难题。大家把字典转换成LRU(Least Recently Used)缓存。

O中华VM 的累累特征都被 Dapper 去掉了,未有身份地图(Identity
Map),未有立异/选用的帮手等。

Dapper 不会管理你总是的生命周期,它一旦它赢得的延续是打开的,并且不存在
DataReader 枚举(除非启用 MA瑞鹰S)。

如何是 马尔斯?它是在创立数据库连接时钦点的,上面是 Dapper 中一而再 SQL
Server 的演示:

public static SqlConnection GetOpenConnection(bool mars = false)

{

    var cs = connectionString;

    if (mars)

    {

        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);

        scsb.MultipleActiveResultSets = true;

        cs = scsb.ConnectionString;

    }

    var connection = new SqlConnection(cs);

    connection.Open();

    return connection;

}

设若钦命了 马尔斯,那么还会创立 SqlConnectionStringBuilder,并点名其
MultipleActiveResultSets 属性为 true。不过,看 Dapper 的例子,貌似
SQL Server 是有 Mars 的,但 MySQL 没有。

限定和注意事项


对于 Dapper
执行的每一种查询的缓存音信,使得它能够神速地物化对象和拍卖参数。当前的兑现把消息缓存在3个ConcurrentDictionary 对象中。它存款和储蓄的指标永远不会被刷新。假设您转移的
SQL 字符串未有采纳参数,那么或者会出现命中内部存储器难点。大家把字典转换到LRU(Least Recently Used)缓存。

O中华VM 的浩大表征都被 Dapper 去掉了,未有地点地图(Identity
Map),未有更新/采纳的帮手等。

Dapper 不会管理你总是的生命周期,它借使它获得的连接是开拓的,并且不设有
DataReader 枚举(除非启用 MAPAJEROS)。

何以是 马尔斯?它是在创建数据库连接时钦定的,下边是 Dapper 中一而再 SQL
Server 的言传身教:

public static SqlConnection GetOpenConnection(bool mars = false)

{

    var cs = connectionString;

    if 

    {

        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder;

        scsb.MultipleActiveResultSets = true;

        cs = scsb.ConnectionString;

    }

    var connection = new SqlConnection;

    connection.Open();

    return connection;

}

设若内定了 马尔斯,那么还会创建 SqlConnectionStringBuilder,并内定其
MultipleActiveResultSets 属性为 威尼斯人线上娱乐,true。不过,看 Dapper 的例子,貌似
SQL Server 是有 Mars 的,但 MySQL 没有。

多重映射

Dapper允许将单个行映射到四个指标。
即使想制止非亲非故的查询和当下加载关联,那是一个很重大的风味。

例子:

沉凝那八个类: Post and User

class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public User Owner { get; set; }
}

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

前些天大家要把posts表单与users表单举办映射查询。到近年来截止,如若我们必要结合一个查询的结果,大家要求八个新的靶子来抒发它,但在那种处境下将User对象放在Post对象中更有意义。

那是多重映射的用户案例。你告知dapper查询重返多少个Post和一个User指标,然后给它描述您想要对蕴涵PostUser对象的每一行做什么样的函数。
在我们的例子中,大家想要获取用户对象并将其放在post对象中。所以编写函数如下:

(post, user) => { post.Owner = user; return post; }

Query主意的3个项目参数钦赐dapper应该利用什么对象及重临的剧情开始展览反体系化行。大家将把那两行解释为PostUser的结缘,然后大家回去三个Post目的。
由此类型申明变为

<Post, User, Post>

有着东西都位居1起,看起来像那样:

var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";

var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();

Assert.Equal("Sams Post1", post.Content);
Assert.Equal(1, post.Id);
Assert.Equal("Sam", post.Owner.Name);
Assert.Equal(99, post.Owner.Id);

Dapper能够透过要是Id列被命名叫“Id”或“id”来拆分再次来到的行。
要是主键差别可能希望将行拆分为“Id”以外的别的地方,请使用可选的splitOn参数。

Dapper 能运转在本人的 db 提供者上吗?


Dapper 能运作在富有 .net ado 提供者上,包罗sqlite,sqlce,firebird,oracle,MySQL,PostgreSQL 和 SQL Server。

Dapper 能运作在作者的 db 提供者上啊?


Dapper 能运维在具有 .net ado 提供者上,包括sqlite,sqlce,firebird,oracle,MySQL,PostgreSQL 和 SQL Server。

多重结果

Dapper允许在单个查询中拍卖多少个结果。

例子:

var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
   var customer = multi.Read<Customer>().Single();
   var orders = multi.Read<Order>().ToList();
   var returns = multi.Read<Return>().ToList();
   ...
}

有例子的一体化例子列表吗?


Dapper
在测试项目中有完整的测试套件。

有例子的欧洲经济共同体例子列表吗?


Dapper 在测试项目中有完整的测试套件。

储存进度

Dapper完全支持存款和储蓄进度:

var user = cnn.Query<User>("spGetUser", new {Id = 1},
        commandType: CommandType.StoredProcedure).SingleOrDefault();

若是你想要更幽默的东西,你能够这么做:

var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure);

int b = p.Get<int>("@b");
int c = p.Get<int>("@c");

何人在采纳 Dapper?


当前应用 Dapper 的有 Stack Overflow 和
helpdesk。

(if you would like to be listed here let me know)

什么人在选择 Dapper?


时下使用 Dapper 的有 Stack Overflow 和 helpdesk。

(if you would like to be listed here let me know)

Ansi字符串和varchar

Dapper协理varchar参数,假使利用param在varchar列上执行where子句,请确认保障以那种办法传送它:

Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在SQL
Server中,使用unicode编码查询unicode与ANSI编码或询问非unicode编码时,变得至关心重视要。

参考资料


  • github Dapper
  • stackoverflow
    Dapper
  • A Look at
    Dapper.NET

 

下载 Demo

参考资料


  • github Dapper
  • stackoverflow Dapper
  • A Look at Dapper.NET

 

下载 Demo

每行类型转换

日常,本身梦想将给定表中的全部行视为同1的数据类型。
可是,在某个景况下,可以将差异的行解析为分裂的数据类型是可行的。
这正是IDataReader.GetRowParser派上用场的地点。

若是有3个名叫“Shapes”的多寡库表,在那之中包罗列:IdTypeData,你想要基于Type列的值将它的行解析为CircleSquareTriangle对象。

var shapes = new List<IShape>();
using (var reader = connection.ExecuteReader("select * from Shapes"))
{
    // Generate a row parser for each type you expect.
    // The generic type <IShape> is what the parser will return.
    // The argument (typeof(*)) is the concrete type to parse.
    var circleParser = reader.GetRowParser<IShape>(typeof(Circle));
    var squareParser = reader.GetRowParser<IShape>(typeof(Square));
    var triangleParser = reader.GetRowParser<IShape>(typeof(Triangle));

    var typeColumnIndex = reader.GetOrdinal("Type");

    while (reader.Read())
    {
        IShape shape;
        var type = (ShapeType)reader.GetInt32(typeColumnIndex);
        switch (type)
        {
              case ShapeType.Circle:
                shape = circleParser(reader);
                break;
            case ShapeType.Square:
                shape = squareParser(reader);
                break;
            case ShapeType.Triangle:
                shape = triangleParser(reader);
                break;
              default:
                throw new NotImplementedException();
        }

          shapes.Add(shape);
    }
}

范围与警示

Dapper缓存有关它运转的种种查询的音信,这使它能够高效实现指标并十分的快处理参数。
当前达成将此音讯缓存在ConcurrentDictionary对象中。仅使用叁次的口舌平日会从此缓存中刷新。纵然如此,如若你在不利用参数的情状下动态生成SQL字符串,则恐怕会遇见内部存款和储蓄器难点。

Dapper的简洁性意味着O智跑M附带的很多意义都被剥离了。Dapper担心玖5%的意况,并为您提供大多数时间所需的工具,并不试图缓解全数失水准。

Dapper协助什么数据库?

Dapper没有特定于DB的完结细节,它适用于全体.NET
ADO提供程序,包涵SQLite(https://www.sqlite.org/),SQL),SQL CE,Firebird,Oracle,MySQL,PostgreSQL和SQL
Server。

有整机的例子清单呢?

Dapper有一个完好无损位于测试工程的测试套件。

什么人在用这一个?

Stack Overflow正值使用Dapper。


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图