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

本文源自: 

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

 

特性


Dapper
是一个单独的文件,可以放进你的项目中用来扩展你的IDbConnection接口.

它提供了三个助手:

本文翻译自: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;

原版教程源自:Dapper Tutorial

执行一个查询,并将结果映射到一个动态类型集合中


该方法将执行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教程.GitBook

执行一个命令,不返回结果


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

中文教程PDF:dapper-tutorial-cn

多次执行一个命令


相同的占位符允许您方便有效的多次执行一个命令.

使用例子:

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 – .Net版本的简单对象映射器

性能


Dapper的一个关键特性是性能。以下指标显示对数据库执行500次SELECT语句并返回数据映射到对象,需要多长时间。

性能测试分为三个表格:

  • POCO序列化框架支持从数据库到静态类型化对象,通过使用原始的SQL。
  • 动态序列化框架支持返回动态对象的列表。
  • 典型的框架使用。通常典型框架使用不同于最佳的使用性能明智。通常它不会涉及编写SQL。

发行说明

请见 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

组件

Nuget稳定版:

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

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

PM> Install-Package Dappe

特点

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

它提供了3个使用方法:

500次查询映射的性能-动态类型序列化

Method

Duration

Remarks

DapperExecuteMapperQuery

48ms

Massive

52ms

Simple.Data

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

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

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

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

参数化查询


参数传递匿名类。这允许您命名参数容易和使您能够简单剪切和粘贴SQL代码片段在查询分析器和运行它们。

new {A = 1, B = "b"} // A 会被映射出参数 @A, B 对应 @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);

集合参数的支持


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

多次执行命令

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

示例:

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在返回。这是理想的在大多数情况下,因为它最大限度地减少共享锁在数据库和减少了数据库在网络上的时间。

然而当执行查询您可能需要减少内存占用并根据需要只加载对象。

性能

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

性能测试分为3个列表:

  • 支持从数据库中提取静态类型对象框架的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”参数。

超过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();   ...} 

超过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"); 

发表评论

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