博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dapper的优势(转)
阅读量:5154 次
发布时间:2019-06-13

本文共 6938 字,大约阅读时间需要 23 分钟。

Dapper的优势 

Yamazaki
 发布于 2014/04/04 14:42
 
字数 1860
 
阅读 478
 
收藏  3
 
 

  

假如你喜欢原生的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的连接数据库对象。SqlConnectionpublic 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
SelectColumnCats() { using (IDbConnection conn = OpenConnection()) { const string query = "select * from ColumnCat order by id desc"; return conn.Query
(query,null); } }
就是这么简单,直接在例子中嵌入Sql,很容易扩展为存储过程,可以使用别名使结果集中的列与业务对象模型(ColumnCat)的属性对应。
//下面使用上面的集合显示出分类。List
AllColumnCat =SelectColumnCats().ToList
();foreach (ColumnCat cat in AllColumnCat.Where(c => c.Parentid == 0)) { Response.Write("Name==>" + cat.Name + "\t"); Response.Write("时间==>" + cat.ModifiedOn + "\t"); Response.Write("
"); foreach (ColumnCat c in AllColumnCat .Where
(subColumnCat => subColumnCat.Parentid == cat.Id)) { Response.Write("  ++++"); Response.Write("Name==>" + c.Name + "\t"); Response.Write("时间==>" + c.ModifiedOn + "\t"); Response.Write("
"); } }
//将一级类别和二级类别显示在页面上,如果使用一个递归,很容易实现无限级分类(你懂的)。 //获取单个ColumnCat对象。public ColumnCat SelectColumnCat(int columnCatId) { using (IDbConnection conn = OpenConnection()) { const string query = "select * from ColumnCat where Id=@id"; return conn.Query
(query, new { id=columnCatId}) .SingleOrDefault
(); } }
这里我们传递了一个参数给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
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
(query , (column, columncat) => { column.ColumnCat = columncat; return column; } , null, null, false, "Id", null, null).ToList
(); } }

注: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
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
(query, null).Single
(); 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
(IDbConnection conn, Action
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; } }

 

转载于:https://www.cnblogs.com/LiZhongZhongY/p/10992590.html

你可能感兴趣的文章
Python核心编程——多线程threading和队列
查看>>
Program exited with code **** 相关解释
查看>>
植物大战僵尸中文年度版
查看>>
26、linux 几个C函数,nanosleep,lstat,unlink
查看>>
投标项目的脚本练习2
查看>>
201521123107 《Java程序设计》第9周学习总结
查看>>
Caroline--chochukmo
查看>>
利用jquery的contains实现搜索功能
查看>>
iOS之文本属性Attributes的使用
查看>>
从.Net版本演变看String和StringBuilder性能之争
查看>>
Excel操作 Microsoft.Office.Interop.Excel.dll的使用
查看>>
解决Ubuntu下博通网卡驱动问题
查看>>
【bzoj2788】Festival
查看>>
执行gem install dryrun错误
查看>>
Java SE之正则表达式一:概述
查看>>
HTML5简单入门系列(四)
查看>>
实现字符串反转
查看>>
转载:《TypeScript 中文入门教程》 5、命名空间和模块
查看>>
苹果开发中常用英语单词
查看>>
[USACO 1.4.3]等差数列
查看>>