假如你喜欢原生的Sql语句,又喜欢ORM的简单,那你一定会喜欢上Dapper这款ROM.点击下载
Dapper的优势:
1,Dapper是一个轻型的ORM类。代码就一个SqlMapper.cs文件,编译后就40K的一个很小的Dll.
2,Dapper很快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
3,Dapper支持什么数据库。Dapper支持Mysql,SqlLite,Mssql2000,Mssql2005,Oracle等一系列的数据库,当然如果你知道原理也可以让它支持Mongo db
4,Dapper的r支持多表并联的对象。支持一对多 多对多的关系。并且没侵入性,想用就用,不想用就不用。无XML无属性。代码以前怎么写现在还怎么写。
5,Dapper原理通过Emit反射IDataReader的序列队列,来快速的得到和产生对象。性能实在高高高。
6,Dapper支持net2.0,3.0,3.5,4.0。【如果想在Net2.0下使用,可以去网上找一下Net2.0下如何配置运行Net3.5即可。】
7,Dapper语法十分简单。并且无须迁就数据库的设计。

下面介绍Dapper如何使用,来进行高效开发,以下操作是编译后在Net3.5下操作的例子,Net4.0下大部分函数有默认值,参数很简单。

//数据库里的表:
CREATE TABLE ColumnCat
(
Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
NAME NVARCHAR(150) NULL,
ModifiedOn SMALLDATETIME NULL DEFAULT(GETDATE()),
Parentid INT
) CREATE TABLE Column
(
Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
NAME NVARCHAR(150) NULL,
ModifiedDate SMALLDATETIME NULL DEFAULT(GETDATE()),
ColumnCatid INT null
)

常用的表,分类和内容表,分类可以有下级类别。以下操作基本上都是对这两个表的操作。

//连接数据库字符串。
private readonly string sqlconnection =
"Data Source=RENFB;Initial Catalog=test;User Id=sa;Password=sa;";
//public readonly string mysqlconnectionString =
@"server=127.0.0.1;database=test;uid=renfb;pwd=123456;charset='gbk'";
//获取Sql Server的连接数据库对象。SqlConnection
public SqlConnection OpenConnection()
{
SqlConnection connection = new SqlConnection(sqlconnection);
connection.Open();
return connection;
}
//获取MySql的连接数据库对象。MySqlConnection
//public MySqlConnection OpenConnection()
//{
//     MySqlConnection connection = new MySqlConnection(mysqlconnectionString);
//     connection.Open();
//     return connection;
//}

注:如果需要换成Mysql数据库,只用将获得sql Server的连接数据库对象的函数注释掉,取消MySql的连接数据库对象的函数的注释,一并取消Mysql连接字符串的注释,并修改为自己的连接信息。

Query()方法
Query()是IDbConnection扩展方法并且重载了,从数据库里提取信息,并用来填充我们的业务对象模型。

//先创建一个类,是数据库的ColumnCat表的模型。
public class ColumnCat
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime ModifiedOn { get; set; }
public int Parentid { get; set; }
}
//获取ColumnCat对象的集合。
public IEnumerable<ColumnCat> SelectColumnCats()
{
using (IDbConnection conn = OpenConnection())
{
const string query = "select * from ColumnCat order by id desc";
return conn.Query<ColumnCat>(query,null);
}
}

就是这么简单,直接在例子中嵌入Sql,很容易扩展为存储过程,可以使用别名使结果集中的列与业务对象模型(ColumnCat)的属性对应。

//下面使用上面的集合显示出分类。
List<ColumnCat> AllColumnCat =SelectColumnCats().ToList<ColumnCat>();
foreach (ColumnCat cat in AllColumnCat.Where(c => c.Parentid == 0))
{
Response.Write("Name==>" + cat.Name + "\t");
Response.Write("时间==>" + cat.ModifiedOn + "\t");
Response.Write("<br/>"); foreach (ColumnCat c in AllColumnCat
.Where<ColumnCat>(subColumnCat => subColumnCat.Parentid == cat.Id))
{
Response.Write("&nbsp;&nbsp;++++");
Response.Write("Name==>" + c.Name + "\t");
Response.Write("时间==>" + c.ModifiedOn + "\t");
Response.Write("<br/>");
}
}
//将一级类别和二级类别显示在页面上,如果使用一个递归,很容易实现无限级分类(你懂的)。
//获取单个ColumnCat对象。
public ColumnCat SelectColumnCat(int columnCatId)
{
using (IDbConnection conn = OpenConnection())
{
const string query = "select * from ColumnCat where Id=@id";
return conn.Query<ColumnCat>(query, new { id=columnCatId})
.SingleOrDefault<ColumnCat>();
}
}

这里我们传递了一个参数给Query方法,参数可以是任何对象,其属性在查询中与sql的参数匹配,由于Query总是返回一个集合,我们只需调用SingleOrDefault方法,因为我们知道总是返回0或1行.

//Dapper也可以加载填充嵌套对象,考虑这样一种情形,考虑到新闻的类别属性,返回类别对象,
//我们创建一个Column的类
public class Column
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime ModifiedDate { get; set; }
public ColumnCat ColumnCat { get; set; }
}
//接下来我们来填充我们的业务对象。
public IList<Column> SelectColumnsWithColumnCat()
{
using (IDbConnection conn = OpenConnection())
{
const string query = "select c.Id,c.Name,c.ModifiedDate,c.ColumnCatid
,cat.id,cat.[Name],cat.ModifiedOn,cat.Parentid from [Column] as c
left outer join ColumnCat as cat on c.ColumnCatid=cat.id";
return conn.Query<Column, ColumnCat, Column>(query
, (column, columncat) => { column.ColumnCat = columncat; return column; }
, null, null, false, "Id", null, null).ToList<Column>();
}
}

注:1,在填充嵌套对象的时候,只好执行ToList<>方法,否则回报ExecuteReader 要求已打开且可用的连接。连接的当前状态为已关闭,而单个对象不会报错,估计是using结束后关闭了连接,而嵌套对象在map的时候又执行了ExecuteReader,只好在using结束之前返回list集合。
2,嵌套对象的参数是比较多的,主要是前两个参数,其它参数没用可以设置为null,不过在4.0版本可以只写两个参数,其它参数都有默认值。特别要注意的是splitOn,这个参数不能为空,否则会报对象为引用的错误。【splitOn参数的意思是读取第二个对象的的分割列,从哪个列起开始读取第二个对象,如果表里的自增长列都为Id,可以设置这个参数为”Id”】.

Execute方法
正如Query方法是检索数据的,Execute方法不会检索数据,它与Query方法非常相似,但它总返回总数(受影响的行数),而不是一个对象集合【如:insert update和delete】.

//接下来向数据库里添加一个类别
public int InsertColumnCat(ColumnCat cat)
{
using (IDbConnection conn = OpenConnection())
{
const string query = "insert into ColumnCat([name],ModifiedOn,Parentid)
values (@name,@ModifiedOn,@Parentid)";
int row = conn.Execute(query,cat);
//更新对象的Id为数据库里新增的Id,假如增加之后不需要获得新增的对象,
//只需将对象添加到数据库里,可以将下面的一行注释掉。
SetIdentity(conn,id=>cat.Id=id,"id","ColumnCat");    
return row; }
}
public void SetIdentity(IDbConnection conn, Action<int> setId,string primarykey
,string tableName)
{
if (string.IsNullOrEmpty(primarykey)) primarykey = "id";
if (string.IsNullOrEmpty(tableName))
{
throw new ArgumentException("tableName参数不能为空,为查询的表名");
}
string query = string.Format("SELECT max({0}) as Id FROM {1}", primarykey
, tableName);
NewId identity = conn.Query<NewId>(query, null).Single<NewId>();
setId(identity.Id);
} public class NewId
{
public int Id { get; set; }
}

由于Dapper是通过类的属性自动绑定的,所以增加了NewId类来获取增加对象后的Id,本来打算使用@@identity,Net3.5下使用总是报错,只好使用Max函数获取。当然如果不需要获得更新后的对象的ID,可以不使用SetIdentity,这个函数通用。

//编译Dapper源码生成的是Net4.0下使用的,可以借助Net4.0新增的dynamic动态类型,
//SetIdentity的实现将非常方便。如下:
public void SetIdentity<T>(IDbConnection conn, Action<int> setId)
{
dynamic identity = connection.Query("SELECT @@IDENTITY AS Id").Single();
T newId = (T)identity.Id;
setId(newId);
}
//更新一个类别:
public int UpdateColumnCat(ColumnCat cat)
{
using (IDbConnection conn = OpenConnection())
{
const string query = "update ColumnCat set name=@Name
,ModifiedOn=@ModifiedOn,Parentid=@Parentid where Id=@id";
return conn.Execute(query,cat);
}
}
//删除一个类别:
public int DeleteColumnCat(ColumnCat cat)
{
using (IDbConnection conn = OpenConnection())
{
const string query = "delete from ColumnCat where id=@id";
return conn.Execute(query, cat);
}
}

下面介绍一下Dapper的高级用法

//Dapper对事务处理的例子,如删除类别的同时删除类别下的所有新闻。或者删除产品的同时,
//删除产品图片表里关联的所有图片。
public int DeleteColumnCatAndColumn(ColumnCat cat)
{
using (IDbConnection conn = OpenConnection())
{
const string deleteColumn = "delete from [Column] where ColumnCatid=@catid";
const string deleteColumnCat = "delete from ColumnCat where id=@Id"; IDbTransaction transaction = conn.BeginTransaction();
int row=conn.Execute(deleteColumn, new { catid =cat.Id},transaction,null,null);
row += conn.Execute(deleteColumnCat, new { id=cat.Id},transaction,null,null);
transaction.Commit();
return row;
}
}

Dapper基础用法的更多相关文章

  1. Dapper 基础用法

    Dapper是.Net下的一个简单orm框架,具有以下特点: 1.简单,只需要一个文件即可(SqlMapper.cs) 2.快速,下面是一个查询结果集在500以上的运行速度对比 3.不要求特定的db ...

  2. PropertyGrid控件由浅入深(二):基础用法

    目录 PropertyGrid控件由浅入深(一):文章大纲 PropertyGrid控件由浅入深(二):基础用法 控件的外观构成 控件的外观构成如下图所示: PropertyGrid控件包含以下几个要 ...

  3. logstash安装与基础用法

    若是搭建elk,建议先安装好elasticsearch 来自官网,版本为2.3 wget -c https://download.elastic.co/logstash/logstash/packag ...

  4. elasticsearch安装与基础用法

    来自官网,版本为2.3 注意elasticsearch依赖jdk,2.3依赖jdk7 下载rpm包并安装 wget -c https://download.elastic.co/elasticsear ...

  5. BigDecimal最基础用法

    BigDecimal最基础用法 用字符串生成的BigDecimal是不会丢精度的. 简单除法. public class DemoBigDecimal { public static void mai ...

  6. Vue组件基础用法

    前面的话 组件(Component)是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.根据项目需求,抽象出一些组件,每个组件里包含了展现.功能和样式.每个页面,根据自己所需, ...

  7. Smarty基础用法

    一.Smarty基础用法: 1.基础用法如下 include './smarty/Smarty.class.php';//引入smarty类 $smarty = new Smarty();//实例化s ...

  8. 前端自动化测试神器-Katalon的基础用法

    前言 最近由于在工作中需要通过Web端的功能进行一次大批量的操作,数据量大概在5000左右,如果手动处理, 完成一条数据的操作用时在20秒左右的话,大概需要4-5个人/天的工作量(假设一天8小时的工作 ...

  9. Bootstrap fileinput:文件上传插件的基础用法

    官网地址:http://plugins.krajee.com/ 官网提供的样例:http://plugins.krajee.com/file-input/demo 基础用法一 导入核心CSS及JS文件 ...

随机推荐

  1. javascript中===与==

    == equality 等同,=== identity 恒等. ==, 两边值类型不同的时候,要先进行类型转换,再比较. ===,不做类型转换,类型不同的一定不等. 类型转换规则:Boolean> ...

  2. 三个特殊资源目录 /res/xml /res/raw 和 /assets

    在android开发中,我们离不开资源文件的使用,从drawable到string,再到layout,这些资源都为我们的开发提供了极大的便利,不过我们平时大部分时间接触的资源目录一般都是下面这三个. ...

  3. struts2中利用POI导出Excel文档并下载

    1.项目组负责人让我实现这个接口,因为以前做过类似的,中间并没有遇到什么太困难的事情.其他不说,先上代码: package com.tydic.eshop.action.feedback; impor ...

  4. PHP无限极分类生成树方法

    你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,整理分享了. function genera ...

  5. HDU 1672 Cuckoo Hashing

    Cuckoo Hashing Description One of the most fundamental data structure problems is the dictionary pro ...

  6. 学军NOI训练13 T3 白黑树

    唉,大学军有自己的OJ就是好,无限orz 只有周六的比赛是开放的囧,这场比赛最后因为虚拟机卡住没有及时提交…… 否则就能让大家看到我有多弱了…… 前两题题解写的很详细,可以自己去看,我来随便扯扯T3好 ...

  7. Java Web编程的主要组件技术——JSP

    参考书籍:<J2EE开源编程精要15讲> JSP(Java Server Page)页面由HTML代码和嵌入其中的Java代码组成. 简单的JSP页面如: <html> < ...

  8. UVA 820 Internet Bandwidth 因特网宽带(无向图,最大流,常规)

    题意:给一个无向图,每条边上都有容量的限制,要求求出给定起点和终点的最大流. 思路:每条无向边就得拆成2条,每条还得有反向边,所以共4条.源点汇点已经给出,所以不用建了.直接在图上跑最大流就可以了. ...

  9. UVA 1395 Slim Span (最小生成树,MST,kruscal)

    题意:给一个图,找一棵生成树,其满足:最大权-最小权=最小.简单图,不一定连通,权值可能全相同. 思路:点数量不大.根据kruscal每次挑选的是最小权值的边,那么苗条度一定也是最小.但是生成树有多棵 ...

  10. python - os.path,路径相关操作

    python处理系统路径的相关操作: # -*- coding: utf-8 -*- import os # 属性 print '__file__: %s' % __file__ # 绝对路径(包含文 ...