Dapper - 一款轻量级对象关系映射(ORM)组件,DotNet 下
Dapper - a simple object mapper for .Net
Official Github clone: https://github.com/SamSaffron/dapper-dot-net
Documentation you can improve
The Dapper tag wiki on Stack Overflow can be improved by any Stack Overflow users. Feel free to add relevant information there.
License
Dapper is offered under dual license - take your pick:
Both are liberal licenses allowing you to use, modify and distribute the software as you choose, in both free and commercial works, on an "as is, no warranties" basis (see the linked license terms for details).
Many software repositories (code.google.com, nuget.org) only allow a single license to be listed; we list Apache for convenience - however, either license is acceptable.
Features
Dapper is a single file you can drop in to your project that will extend your IDbConnection interface.
It provides 3 helpers:
Execute a query and map the results to a strongly typed List
Note: all extension methods assume the connection is already open, they will fail if the connection is closed.
public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)
Example usage:
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);
Execute a query and map it to a list of dynamic objects
public static IEnumerable<dynamic> Query (this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)
This method will execute SQL and return a dynamic list.
Example usage:
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);
Execute a Command that returns no results
public static int Execute(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null)
Example usage:
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);
Execute a Command multiple times
The same signature also allows you to conveniently and efficiently execute a command multiple times (for example to bulk-load data)
Example usage:
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"
This works for any parameter that implements IEnumerable<T> for some T.
Performance
A key feature of Dapper is performance. The following metrics show how long it takes to execute 500 SELECT statements against a DB and map the data returned to objects.
The performance tests are broken in to 3 lists:
- POCO serialization for frameworks that support pulling static typed objects from the DB. Using raw SQL.
- Dynamic serialization for frameworks that support returning dynamic lists of objects.
- Typical framework usage. Often typical framework usage differs from the optimal usage performance wise. Often it will not involve writing SQL.
Performance of SELECT mapping over 500 iterations - POCO serialization
| Method | Duration | Remarks |
| Hand coded (using a SqlDataReader) | 47ms | |
| Dapper ExecuteMapperQuery<Post> | 49ms | |
| ServiceStack.OrmLite (QueryById) | 50ms | |
| PetaPoco | 52ms | Can be faster |
| BLToolkit | 80ms | |
| SubSonic CodingHorror | 107ms | |
| NHibernate SQL | 104ms | |
| Linq 2 SQL ExecuteQuery | 181ms | |
| Entity framework ExecuteStoreQuery | 631ms |
Performance of SELECT mapping over 500 iterations - dynamic serialization
| Method | Duration | Remarks |
| Dapper ExecuteMapperQuery (dynamic) | 48ms | |
| Massive | 52ms | |
| Simple.Data | 95ms |
Performance of SELECT mapping over 500 iterations - typical usage
| 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 |
Performance benchmarks are available here: http://code.google.com/p/dapper-dot-net/source/browse/Tests/PerformanceTests.cs , Feel free to submit patches that include other ORMs - when running benchmarks, be sure to compile in Release and not attach a debugger (ctrl F5)
Parameterized queries
Parameters are passed in as anonymous classes. This allow you to name your parameters easily and gives you the ability to simply cut-and-paste SQL snippets and run them in Query analyzer.
new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B
Advanced features
List Support
Dapper allow you to pass in IEnumerable<int> and will automatically parameterize your query.
For example:
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 });
Will be translated to:
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
Buffered vs Unbuffered readers
Dapper's default behavior is to execute your sql and buffer the entire reader on return. This is ideal in most cases as it minimizes shared locks in the db and cuts down on db network time.
However when executing huge queries you may need to minimize memory footprint and only load objects as needed. To do so pass, buffered: false into the Query method.
Multi Mapping
Dapper allows you to map a single row to multiple objects. This is a key feature if you want to avoid extraneous querying and eager load associations.
Example:
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);
important note Dapper assumes your Id columns are named "Id" or "id", if your primary key is different or you would like to split the wide row at point other than "Id", use the optional 'splitOn' parameter.
Multiple Results
Dapper allows you to process multiple result grids in a single query.
Example:
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();
...
}
Stored Procedures
Dapper supports fully stored procs:
var user = cnn.Query<User>("spGetUser", new {Id = 1},
commandType: CommandType.StoredProcedure).First();}}}
If you want something more fancy, you can do:
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 and varchar
Dapper supports varchar params, if you are executing a where clause on a varchar column using a param be sure to pass it in this way:
Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });
On Sql Server it is crucial to use the unicode when querying unicode and ansi when querying non unicode.
Limitations and caveats
Dapper caches information about every query it runs, this allow it to materialize objects quickly and process parameters quickly. The current implementation caches this information in a ConcurrentDictionary object. The objects it stores are never flushed. If you are generating SQL strings on the fly without using parameters it is possible you will hit memory issues. We may convert the dictionaries to an LRU Cache.
Dapper's simplicity means that many feature that ORMs ship with are stripped out, there is no identity map, there are no helpers for update / select and so on.
Dapper does not manage your connection's lifecycle, it assumes the connection it gets is open AND has no existing datareaders enumerating (unless MARS is enabled)
Will dapper work with my db provider?
Dapper has no DB specific implementation details, it works across all .net ado providers including sqlite, sqlce, firebird, oracle, MySQL and SQL Server
Do you have a comprehensive list of examples?
Dapper has a comprehensive test suite in the test project: http://code.google.com/p/dapper-dot-net/source/browse/Tests/Tests.cs
Who is using this?
Dapper is in production use at:
Stack Overflow , xpfest.com helpdesk, worldcitycard, roadmap
(if you would like to be listed here let me know)
Tools and extensions for Dapper (3rd party)
Dapper extensions Sqlinq SalarDbCodeGenerator
Dapper - 一款轻量级对象关系映射(ORM)组件,DotNet 下的更多相关文章
- Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包
Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...
- 对象关系映射ORM
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效 ...
- Django 源码小剖: Django 对象关系映射(ORM)
引 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django O ...
- Python 3 对象关系映射(ORM)
ORM 对象关系映射 Object Relational Mapping 表 ---> 类 字段 ---> 属性 记录 ---> 对象 # mysql_client.py impor ...
- 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).
通过阅读MongoDB 3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...
- 对象-关系映射ORM(Object Relational Mapping)(转)
ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现 Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件 ...
- 对象关系映射(ORM)框架GreenDao简介和基本使用
官网上的介绍,greenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案. GreenDao特点 性能最大化,可能是Android平台上最快的ORM框架 易于使用的A ...
- 对象关系映射 ORM
1.1 作用 MTV框架中包括一个重要的部分,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因 ...
- Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite
Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射 ...
随机推荐
- HashMap中 工具方法tableSizeFor的作用
[转] https://blog.csdn.net/fan2012huan/article/details/51097331 首先看下该方法的定义以及被使用的地方 static final int t ...
- Linux 内存释放
简介 linux 内存释放通过如下命令,将cache与buff根据环境进行释放操作,避免重启释放内存. 操作 1.将内存中buff数据保存磁盘 sync 2.清理cache与buff缓存 echo 3 ...
- python库的tkinter带你进入GUI世界(计算器简单功能)
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 一个处女座的程序猿 PS:如有需要Python学习资料的小伙伴可以加 ...
- Java生鲜电商平台-Spring Cloud微服务架构图
- CAS(比较并交换)
一.CAS(无锁的执行者) CAS包含3个参数:内存值 V 旧的预期值 A 新值 B 当且仅当V值等于A值时,将V的值改为B值,如果V值和A值不同,说明已经有其他线程做了更新,则当前线程什么都不 ...
- DQL---连接查询(内连接、外连接)、子查询、分页查询
一.连接查询 1.连接查询建立在有相互关系的两个表间,进行两个及两个以上的表或视图的查询. 2.对n张表进行查询,至少需要n-1个连接表的条件. 二.笛卡尔积(容易造成数据库宕机) 1.指表中每行元素 ...
- 2019年上半年收集到的人工智能AutoML干货文章
2019年上半年收集到的人工智能AutoML干货文章 自动机器学习简述(AutoML) 谷歌将AutoML应用于Transformer架构,翻译结果飙升,已开源 IBM推出AutoAI,让企业人工智能 ...
- CocoPods原理
CocoaPods 的原理是将所有的依赖库都放到另一个名为Pods的项目中, 然而让住项目依赖Pods项目, 这样,源码管理工作任务从主项目移到了Pods项目中. 1.Pods项目最终会编译成一个名为 ...
- [b0008] Windows 7 下 hadoop 2.6.4 eclipse 本地开发调试配置
目的: 基于上篇的方法介绍,开发很不方便 .[0007] windows 下 eclipse 开发 hdfs程序样例 装上插件,方便后续直接在windows下的IDE开发调试. 环境: Linux ...
- 编译 lineageos 14.1 on OnePlus3
breakfast oneplus3 命令的主要作用是 1.执行 vendorsetup.sh 2. variant 默认设置为 userdebug 3. 根据机型判断 调用 lunch cm 或 ...