C#的dapper使用

C#的Dapper使用

标签(空格分隔): 未分类


摘要

  • 本文主要讨论ORM技术和Dapper框架。
  • 先介绍ORM是什么——一种对象关系映射的技术;再介绍为什么引入ORM——将关系型数据库映射成面向对象编程,简化程序员的操作;而后介绍ORM具体怎么用——Dapper框架。
  • 在介绍dapper框架时我们引入了适配层概念,以期更易理解dapper的思想。
  • 最后介绍Dapper的安装,基本用法,和复杂操作

ORM(Object Relation Mapping)

ORM是什么?

从字面理解,O是Object,对象;R是Relation,关系;M是Mapping,映射。所以,用一句话概括就是:ORM是一种对象关系映射的技术

为什么引入ORM?

我们平时所使用的大多数编程模型都是面向对象编程,就是把我们研究的问题抽象出来分解成一个个对象,对象有属性,方法等等,我们操作的是对象。比如一个学生就是一个对象,他有身高,体重等属性,还有高数书这个属性,高数书本身又是一个对象,高数书有价格,作者,主人等,该学生还有跑步,学习等方法。
我们可以操作学生跑步,可以操作学生学习,可以操作学生再买一本英语书等等。我们还可以对学生的属性高数书这个对象操作,例如把他丢弃。所以,我们操作的是对象,这就是面向对象编程。
而我们平时所使用的数据库是关系型数据库,他是从集合论等数学知识发展过来的,他讲究集合,映射,六大范式等等,跟我们的面向对象思想的封装继承多态不同,这两者之间有着根本性的差异。
所以我们就存在一个问题,怎么去调和二者,如果能有一种技术把对象与数据库对应起来,我们编程就会方便许多。于是,ORM应运而生,他就是为了解决对象与数据库之间的差异所产生的一门技术,用他可以把对象与数据库建立一种映射,对于业务层的程序员,他不用管数据库的结构,他只需要专注于他的业务逻辑去操作对象。至于对象怎么去变成元组进入数据库,以及怎么从数据库取数据变成对象,那是ORM自动解决的。

ORM怎么用?

既然ORM这么方便,我们该怎么去使用呢?其实每种语言,都有自己的ORM,各种ORM层出不穷,许多程序员还喜欢自己去写一个ORM,这里哈希君只介绍C#下的Dapper框架。
在介绍Dapper之前,哈希君想跟大家讨论一下适配层的概念,以期更好理解这个框架。


适配层

我们先来看看一台计算机,他的最底层是硬件,然后在这之上加了一层操作系统,操作系统负责对硬件的抽象和对资源的管理。这样,无论我们的CPU是什么架构的,网卡是什么厂商的,内存条是多大的,只要有了操作系统,他就可以把这些硬件全部抽象和管理出来,向上提供一个统一的接口,我们应用层就无需管硬件了,只需要专注于接口就行了。所以这里操作系统就充当了一个适配层的概念,他把底下各种乱七八糟不同的硬件全部适配出来给应用层提供一个统一的接口,我们只要调这个接口就可以操作硬件了,而不用管这个硬件是怎么样的,是不是方便多了。
同样,浏览器也是一个适配层。无论你是Windows也好,Linux也好,笔记本也好,手机也好,浏览器把他们全部适配出来,这样网站就不用管这些细节了,他只需要专注于他的网站内容,至于怎么渲染是浏览器的事情,浏览器会自动去适配的。所以浏览器又是各种操作系统的适配层。
那么,我们的Dapper也是一个适配层,他可以把错综复杂,恩怨纠葛的带有各种约束的数据库表抽象出来,向上提供一个统一的接口,对于程序员来说,只需要专注于业务逻辑即可。


Dapper

至此,终于到了本文的重点——Dapper,.NET下的一种ORM框架。

Dapper的安装[1]

方法一:使用NuGet安装
打开visual studio的项目,依次点击工具NuGet包管理器管理解决方案的NuGet程序包

LRHA{0TVII0W6B7VNHX3VGR.jpg

再点击浏览搜索dapper点击搜索结果中的Dapper勾选项目选择安装;

DTL$~J)8V@{C5}2BFJN@$8O.png

解决方案管理器中点击项目查看引用,如果有Dapper,说明安装成功。

Z6A3%}8V8)O1MT@@~PE`MCH.png

方法二:直接在官网[2]下载源代码,加入项目。这种方法哈希君没有试,不过可以参考链接Dapper快速学习

Dapper的基本用法[3]

首先,我们在Model层写一个Person类,他有ID,Name,Remark。
![(UBQ}]CQ32{{VW`1EGPJ5MQ.png](http://upload-images.jianshu.io/upload_images/4052700-01cbfcab5e889f51.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

同样我们在数据库也有一个Person表,包含id,name,remark三个字段,其中id是主键自增。

而后我们在DAL层写一个PersonDB类,提供对Person的基本访问。connectionString是数据库连接字符串,由配置文件读取。

插入操作

将一个对象person插入数据库的方法如图。


Q_{~JX7~%Q3512XFJM9DG{W.png

插入代码文本如下。@Name的意思是自动将person里的Name值绑定上去。

public static int Insert(Person person)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("insert into Person(Name,Remark) values(@Name,@Remark)", person);
}
}

批量插入:

/// <summary>
/// 批量插入Person数据,返回影响行数
/// </summary>
/// <param name="persons"></param>
/// <returns>影响行数</returns>
public static int Insert(List<Person> persons)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("insert into Person(Name,Remark) values(@Name,@Remark)", persons);
}
}

删除操作

public static int Delete(Person person)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("delete from Person where id=@ID", person);
}
}

public static int Delete(List<Person> persons)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("delete from Person where id=@ID", persons);
}
}

修改操作

public static int Update(Person person)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("update Person set name=@name where id=@ID", person);
}
}

public static int Update(List<Person> persons)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Execute("update Person set name=@name where id=@ID", persons);
}
}

查询操作

/// <summary>
/// 无参查询所有数据
/// </summary>
/// <returns></returns>
public static List<Person> Query()
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Query<Person>("select * from Person").ToList();
}
}

/// <summary>
/// 查询指定数据
/// </summary>
/// <param name="person"></param>
/// <returns></returns>
public static Person Query(Person person)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    return connection.Query<Person>("select * from Person where id=@ID", person).SingleOrDefault();
}
}

Dapper的复杂操作[4]

查询的In操作

/// <summary>
/// In操作
/// </summary>
public static List<Person> QueryIn()
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    var sql = "select * from Person where id in @ids";
    //参数类型是Array的时候,dappper会自动将其转化
    return connection.Query<Person>(sql, new { ids = new int[2] { 1, 2 }, }).ToList();
}
}

public static List<Person> QueryIn(int[] ids)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    var sql = "select * from Person where id in @ids";
    //参数类型是Array的时候,dappper会自动将其转化
    return connection.Query<Person>(sql, new { ids }).ToList();
}
}

多语句操作

为此我们引入以下Book类,同样在数据库里设置这个表。

public class Book
{
public int ID { get; set; }
public int PersonID { get; set; }
public string BookName { get; set; }
}
/// <summary>
/// 多语句操作
/// </summary>
public static void QueryMultiple()
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    var sql = "select * from Person; select * from Book";
    var multiReader = connection.QueryMultiple(sql);
    var personList = multiReader.Read<Person>();
    var bookList = multiReader.Read<Book>();
    multiReader.Dispose();
}
}

Join操作

我们是面向对象编程,所以一个对象里面会有许多其他子对象,这个子对象里面又有其自己的子对象,这种关系在数据库里的表示就是外键。
比如我们有一本书book,它有主人person,book是一个对象,主人又是一个对象。

public class BookWithPerson
{
public int ID { get; set; }
public Person Pers { get; set; }
public string BookName { get; set; }
}

我们自然想要一个方法把数据库里复杂的外键关系转成我们需要的对象BookWithPerson,所有我们需要的信息都存在里面,取数据的时候只要找这个对象取数据就行了,比如我们需要一本书的主人的姓名,我们只需要bookWithPerson.Pers.Name。如果是一对多的关系我们用数组,如果是多对多我们加一层mapping。
现在我们想根据书的ID查询书的信息,包括主人信息。那么

public static BookWithPerson QueryJoin(Book book)
{
using (IDbConnection connection = new SqlConnection(connectionString))
{
    var sql = @"select b.id,b.bookName,p.id,p.name,p.remark
                        from Person as p
                        join Book as b
                        on p.id = b.personId
                        where b.id = @id;";
    var result = connection.Query<BookWithPerson, Person, BookWithPerson>(sql,
        (bookWithPerson, person) =>
        {
            bookWithPerson.Pers = person;
            return bookWithPerson;
        },
        book);
    //splitOn: "bookName");
    return (BookWithPerson)result;
}
}

其中,Query的三个泛型参数分别是委托回调类型1委托回调类型2返回类型。形参的三个参数分别是sql语句map委托对象参数。所以整句的意思是先根据sql语句查询;同时把查询的person信息赋值给bookWithPerson.Pers,并且返回bookWithPerson;book是对象参数,提供参数绑定的值。
最终整个方法返回BookWithPerson,这样我们所需要的所有信息就有了。


有什么错误的地方欢迎指正!谢谢!


参考资料


  1. Dapper快速学习

  2. Dapper的git地址

  3. Dapper,Net下无敌的ORM

  4. Dapper中的一些复杂操作

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容