Dapper.Net by example

januari 6, 2012

When the team behind StackOverflow released the mini-ORM Dapper, we were enthousiastic. An ORM with performance in mind!

Microsoft’s Entity Framework is still lagging behind and feels (is) like a beast. NHibernate is a beast as well, but is usally fast with second-level caching. For simple applications or scheduled tasks, it just too much. And for poorly designed legacy databases, it works against you. When you just need to write SQL queries and want to map the results to objects, a mini ORM suffices.

StackOverflow is one of the most responsive sites I know, so its ORM performance’s is proven. Dapper’s documentation however is somewhat sparse.

Basic usage

Download the single file SqlMapper.cs and dump it in your project.
Put using Dapper in your file with queries, because Dapper extends the normal IDbConnection interface (which is somewhat of a bad practice imho).
Use your favorite way (Dependency Injection of course) of providing a IDbConnection connection named conn,just as you normally would when using a ADO.NET. Basically like so:

using (var conn = new SqlConnection(myConnectionString)) {
conn.Open();
....
}

A list of objects

Select a list of accounts from a certain webshop.

IEnumerable<Account> resultList = conn.Query<Account>(@"
SELECT *
FROM Account
WHERE shopId = @ShopId",
new { ShopId = shopId });

The Account object is for example.

public class Account {
public int? Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public int ShopId {get; set;}
}

Note that eventhough we use SELECT *, not all fields have to be present as class properties.

A single object

Account result = conn.Query<Account>(@"
SELECT *
FROM Account
WHERE Id = @Id",
new { Id = Id }).FirstOrDefault();

A dynamic object

If you’re too lazy to type out a class, you can use a dynamic object.

dynamic account = conn.Query<dynamic>(@"
SELECT Name, Address, Country
FROM Account
WHERE Id = @Id", new { Id = Id }).FirstOrDefault();
Console.WriteLine(account.Name);
Console.WriteLine(account.Address);
Console.WriteLine(account.Country);

Nice! Probably somewhat slower than if you type out the class.

A list of objects with single child object (multimap)

Imagine we want the Shop data with the Accounts as well. It is a legacy database, so the Shop’s Id is named ShopId instead of Id. This can be overcome with the ‘splitOn’ option.

public class Account {
public int? Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public int ShopId {get; set;}
public Shop Shop {get;set;}
}
public class Shop {
public int? ShopId {get;set;}
public string Name {get;set;}
public string Url {get;set;}
} var resultList = conn.Query<Account, Shop, Account>(@"
SELECT a.Name, a.Address, a.Country, a.ShopId
s.ShopId, s.Name, s.Url
FROM Account a
INNER JOIN Shop s ON s.ShopId = a.ShopId
", (a, s) => {
a.Shop = s;
return a;
},
splitOn: "ShopId"
).AsQueryable();

A parent object with its child objects

And the other way around: find the shop with all its accounts. It’s a little more complicated, as each row is given as (Shop s, Account a), but Shop s is a new object every time. So we have to remember one shop to add all accounts to.

public class Shop {
public int? Id {get;set;}
public string Name {get;set;}
public string Url {get;set;}
public IList<Account> Accounts {get;set;}
} public class Account {
public int? Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public int ShopId {get;set;}
} var lookup = new Dictionary<int, Shop>()
conn.Query<Shop, Account, Shop>(@"
SELECT s.*, a.*
FROM Shop s
INNER JOIN Account a ON s.ShopId = a.ShopId
", (s, a) => {
Shop shop;
if (!lookup.TryGetValue(s.Id, out shop)) {
lookup.Add(s.Id, shop = s);
}
if (shop.Accounts == null)
shop.Accounts = new List<Account>();
shop.Accounts.Add(a);
return shop;
},
).AsQueryable(); var resultList = lookup.Values;

I got this dapper test ParentChildIdentityAssociations: https://code.google.com/p/dapper-dot-net/source/browse/Tests/Tests.cs#1343

Insert and update

Insert and update is not part of the default Dapper file. However, these is an extension for these functions — which usually are the most tedious to maintain, so it is more than welcome.

Mark you identifier with [KeyAttribute]

public class Account {
[KeyAttribute]
public int? Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public int ShopId {get; set;}
}

And then you can create a simple Persist function:

        public void Persist(IDbConnection conn, Account acc) {
if (acc.Id == null) {
SqlMapperExtensions.Insert(conn, acc);
}
else {
SqlMapperExtensions.Update(conn, acc);
}
}

Dapper Use For Net的更多相关文章

  1. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  2. Dapper扩展之~~~Dapper.Contrib

    平台之大势何人能挡? 带着你的Net飞奔吧!http://www.cnblogs.com/dunitian/p/4822808.html#skill 上一篇文章:Dapper逆天入门~强类型,动态类型 ...

  3. 由Dapper QueryMultiple 返回数据的问题得出==》Dapper QueryMultiple并不会帮我们识别多个返回值的顺序

    异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#dapper 今天帮群友整理Dapper基础教程的时候手脚快了点,然后遇到了一个小问题,Dapp ...

  4. Dapper.Contrib:GetAsync<T> only supports an entity with a [Key] or an [ExplicitKey] property

    异常处理:http://www.cnblogs.com/dunitian/p/4523006.html#dapper 原来Model是这样滴 修改后是这样滴 注意点:Model里面的Table和Key ...

  5. Dapper where Id in的解决方案

    简单记一下,一会出去有点事情~ 我们一般写sql都是==>update NoteInfo set NDataStatus=@NDataStatus where NId in (@NIds) Da ...

  6. ASP.NET Core 1.0 使用 Dapper 操作 MySql(包含事务)

    操作 MySql 数据库使用MySql.Data程序包(MySql 开发,其他第三方可能会有些问题). project.json 代码: { "version": "1. ...

  7. Asp.Net Core + Dapper + Repository 模式 + TDD 学习笔记

    0x00 前言 之前一直使用的是 EF ,做了一个简单的小项目后发现 EF 的表现并不是很好,就比如联表查询,因为现在的 EF Core 也没有啥好用的分析工具,所以也不知道该怎么写 Linq 生成出 ...

  8. 搭建一套自己实用的.net架构(3)续 【ORM Dapper+DapperExtensions+Lambda】

    前言 继之前发的帖子[ORM-Dapper+DapperExtensions],对Dapper的扩展代码也进行了改进,同时加入Dapper 对Lambda表达式的支持. 由于之前缺乏对Lambda的知 ...

  9. mono for android中使用dapper或petapoco对sqlite进行数据操作

    在mono for android中使用dapper或petapoco,很简单,新建android 类库项目,直接把原来的文件复制过来,对Connection连接报错部分进行注释和修改就可以运行了.( ...

  10. Dapper:The member of type SeoTKD cannot be used as a parameter Value

    异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#dapper 上次说了一下Dapper的扩展Dapper.Contrib http://www. ...

随机推荐

  1. http知识累积

    1. http头 Host, Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的. 如果有黑客劫持了用户的请求,篡改了Host的内容,当请求到 ...

  2. 外包如何安排人手-b

    前几天跟一位做人事的朋友聊天,说起软件行业人员问题.朋友的公司是做软件外包的.一个APP项目基本配置6-7个人,每个Android.ios.后台都各配2人以上,但是项目各种超期.各种无法交付.各种客户 ...

  3. 《深入剖析Tomcat》阅读(三)

    这里要介绍下Tomcat的一个重要设计方法,Catalina设计方式. Servlet容器是一个复杂系统,但是,它有三个基本任务,对每个请求,servlet容器会为其完成以下三个操作: 1.创建一个R ...

  4. tyvj P1135 - 植物大战僵尸 最大权闭合图

    P1135 - 植物大战僵尸 From ytt    Normal (OI)总时限:10s    内存限制:128MB    代码长度限制:64KB 背景 Background 虽然这么多天了,,虽然 ...

  5. Python on Android

    Python on Android Posted on April 29, 2015 by Alexander Taylor   There are an increasing number of r ...

  6. C模块划分

    模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求.C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行 ...

  7. QT变异版本下载(SJLJ长跳转,DWARF不传递错误(32位专用),SEH(64位专用)),以及QT的实验室项目

    http://www.tver-soft.org/ http://sourceforge.net/projects/qt64ng/ ---------------------------------- ...

  8. lc面试准备:Number of 1 Bits

    1 题目 Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also ...

  9. python中文乱码例子

    #coding=utf-8 #---中文乱码--- #直接打印中文 print '千里之外取人首级,瞬息之间爆人菊花.' #中文前面加u,变成Unicode编码 print u'千里之外取人首级' # ...

  10. maya 操作自我整理(一)

    绘制曲线时的点的控制 当我们在使用CV Curve Tool或者EP Curve Tool创建NURBS曲线的过程中,按下"Insert"键,配合键盘上的上.下箭头方向键,可以自由 ...