Dapper上手

一、Dapper特点

   Dapper 特点:    小型ORM:Dapper是一个轻型的ORM类。源码代码量少,编译后就40K的一个很小的Dll.;    速度快:Dapper的速度接近与IDataReader,取列表的数据超过了DataTable;    支持多数据库:Dapper支持Mysql,SqlLite,Mssql,Oracle等一系列的数据库;    灵活性高:支持一对多 多对多的关系,无XML无属性。代码以前怎么写现在还怎么写;    性能高:通过Emit反射IDataReader的序列队列,来快速的得到和产生对象;    支持.net版本:支持多个版本.Net,如:.Net Framework和.Net Core;    可扩展性强:语法简单,并且无须迁就数据库的设计。

二、常用方法

1.准备

安装

本文使用的是.Net6版本,通过NuGet安装相应版本的Dapper和MySql.Data:

dotnet add package Dapper --version 2.0.123

dotnet add package MySql.Data --version 8.0.32.1

创建表格,这里使用的是MySql5.5:

/* 创建表 */

CREATE TABLE `assignment` (

`assignmentNo` decimal(4,0) NOT NULL,

`empno` varchar(10) DEFAULT NULL,

`content` varchar(50) DEFAULT NULL,

PRIMARY KEY (`assignmentNo`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `dept` (

`deptno` decimal(4,0) NOT NULL,

`deptname` varchar(20) DEFAULT NULL,

PRIMARY KEY (`deptno`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `emp` (

`empno` decimal(4,0) NOT NULL,

`ename` varchar(10) DEFAULT NULL,

`job` varchar(20) DEFAULT NULL,

`hiredate` datetime DEFAULT NULL,

`sal` decimal(10,0) DEFAULT NULL,

`deptno` decimal(4,0) DEFAULT NULL,

PRIMARY KEY (`empno`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Dapper使用三个步骤: 创建一个IDbConnection接口对象; 编写一个查询SQL来执行CRUD操作; 将查询SQL作为Execute方法的参数传递。

2. Execute

Execute 是一个可以从 IDbConnection 类型的任意对象调用的扩展方法,它可以执行一个或多个命令并返回受影响的行数。

参数:

参数含义sql要执行的命令文本param命令参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

代码如下(示例):

INSERT语句

执行单次INSERT语句

string sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) Values (@empno,@ename,@job,@hiredate,@sal);";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { empno = 7369, ename = "SMITH", job = "SALESMAN", hiredate = "2022-4-1", sal = 9000 });

}

 执行多次INSERT语句 

string sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) Values (@empno,@ename,@job,@hiredate,@sal);";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new { empno = 7779 , ename = "宋江",job= "SALESMAN", hiredate="2022-5-1",sal =9000 },

new { empno = 7780 , ename = "李逵",job= "SALESMAN", hiredate="2022-6-1",sal =9000 },

new { empno = 7781 , ename = "关胜",job= "SALESMAN", hiredate="2022-6-1",sal =9000 },

new { empno = 7782 , ename = "白日鼠",job= "SALESMAN", hiredate="2022-6-1",sal =9000 },

});

}

UPDATE语句

执行单次UPDATE语句 

string sql = "UPDATE emp SET ename =@ename WHERE empno =@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { empno = 7369, ename = "yulan" });

}

执行多次UPDATE语句 

string sql = "UPDATE emp SET ename =@ename WHERE empno =@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new { empno =7369,ename ="卢俊义" },

new { empno =7777,ename ="林冲"}

});

}

DELETE语句

执行单次DELETE语句 

string sql = "DELETE FROM emp WHERE empno =@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { empno = 7780 });

}

执行多次DELETE语句 

string sql = "DELETE FROM emp WHERE empno =@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new{ empno = 7781 },

new{ empno = 7782 }

});

}

有参存储过程

执行单次存储过程 

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { param_empno = 7777, param_ename = "卢俊义123" }, commandType: CommandType.StoredProcedure);

}

执行多次存储过程 

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new { param_empno = 7777, param_ename = "林冲" },

new { param_empno = 7778, param_ename = "宋江" },

},

commandType: CommandType.StoredProcedure);

}

2.Query

Query是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以执行查询并映射结果。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)buffered是否从缓冲读取查询结果(默认为true)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

代码如下(示例):

查询匿名类型

string sql = "SELECT * FROM emp";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emps = connection.Query(sql).ToList();

}

查询强类型 

string sql = "SELECT * FROM emp";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emps = connection.Query(sql).ToList();

}

查询多映射(一对一) 

string sql = "SELECT * FROM emp INNER JOIN dept ON emp.deptno = dept.deptno;";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emps = connection.Query(sql,

(emps, dept) =>

{

emps.deptInfo = dept;

return emps;

},

splitOn: "deptno").Distinct().ToList();

}

 查询多映射(一对多)

string sql = "SELECT * FROM emp INNER JOIN assignment ON emp.empno = assignment.empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var empAssignment = new Dictionary();

var emps = connection.Query(sql,

(emp, assignment) =>

{

Emp empEntity;

if (!empAssignment.TryGetValue(emp.empno, out empEntity))

{

empEntity = emp;

empEntity.assignments = new List();

empAssignment.Add(empEntity.empno, empEntity);

}

empEntity.assignments.Add(assignment);

return empEntity;

},splitOn: "empno").Distinct().ToList();

}

3.QueryFirst

QueryFirst是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以执行查询并映射第一个结果。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

First, Single和Default比较

方法查询没有结果时有一条数据有多条数据First抛异常当前项第一项Single抛异常当前项抛异常FirstOrDefault默认值当前项第一项SingleOrDefault默认值当前项抛异常

查询匿名类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QueryFirst(sql, new { empno = 7777 });

}

查询强类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QueryFirst(sql, new { empno = 7777 });

}

4.QueryFirstOrDefault

QueryFirstOrDefault是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以执行查询并映射第一个结果,如果序列不包含任何元素则为默认值。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

First, Single和Default比较

方法查询没有结果时有一条数据有多条数据First抛异常当前项第一项Single抛异常当前项抛异常FirstOrDefault默认值当前项第一项SingleOrDefault默认值当前项抛异常

查询匿名类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QueryFirstOrDefault(sql, new { empno = 7777 });

}

查询强类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QueryFirstOrDefault(sql, new { empno = 7777 });

}

5.QuerySingle

QuerySingle是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以执行查询并映射第一个结果,如果序列中没有元素则会引发异常。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

查询匿名类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QuerySingle(sql, new { empno = 7777 });

}

查询强类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QuerySingle(sql, new { empno = 7777 });

}

6.QuerySingleOrDefault

QuerySingleOrDefault是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以执行查询并映射第一个结果,如果序列为空则为默认值。如果序列中有多个元素,则此方法将引发异常。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

查询匿名类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QuerySingleOrDefault(sql, new { empno = 7777 });

}

查询强类型

string sql = "SELECT * FROM emp WHERE empno=@empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emp = connection.QuerySingleOrDefault(sql, new { empno = 7777 });

}

7.QueryMultiple

QueryMultiple是一个可以从IDbConnection类型的任意对象调用的扩展方法,它可以在相同的命令和映射结果中执行多个查询。

参数:

参数含义sql要执行的查询param查询参数(默认为null)transaction需要使用的事务(默认为null)commandTimeout命令执行超时时间(默认为null)commandType命令类型(默认为null)

QueryMultiple方法

string sql = "SELECT * FROM emp WHERE empno =@empno;SELECT * FROM assignment WHERE assignmentNo =@assignmentNo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

using (var multi = connection.QueryMultiple(sql, new { empno = 7777, assignmentNo=1 }))

{

var emps = multi.Read().First();

var assignments = multi.Read().ToList();

}

}

三、参数

1.匿名类型参数

Dapper通过支持匿名类型使其可以简单、安全(SQL注入)的使用参数。

单次执行

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { param_empno = 7777, param_ename = "卢俊义007" }, commandType: CommandType.StoredProcedure);

}

多次执行

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new { param_empno = 7777, param_ename = "林冲" },

new { param_empno = 7778, param_ename = "宋江" },

},

commandType: CommandType.StoredProcedure);

}

2.动态类型参数

在Dapper方法中创建并使用参数。

单次执行

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

DynamicParameters parameter = new DynamicParameters();

parameter.Add("@param_empno", 7777, DbType.Decimal, ParameterDirection.Input);

parameter.Add("@param_ename", "555", DbType.String, ParameterDirection.Input);

parameter.Add("@result_count", dbType: DbType.Int32, direction: ParameterDirection.Output);

connection.Execute("sp_ChangeEmpInfo", parameter, commandType: CommandType.StoredProcedure);

int rowCount = parameter.Get("@result_count");

}

多次执行

var sql = "sp_ChangeEmpInfo";

var parameters = new List();

for (var i = 0; i < 3; i++)

{

var p = new DynamicParameters();

p.Add("@param_empno", 7777+i, DbType.Int32, ParameterDirection.Input);

p.Add("@param_ename", "卢俊义" + (i + 1), DbType.String, ParameterDirection.Input);

p.Add("@result_count", dbType: DbType.Int32, direction: ParameterDirection.Output);

parameters.Add(p);

}

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

connection.Execute(sql, parameters, commandType: CommandType.StoredProcedure);

int rowCount = parameters.Sum(x => x.Get("@result_count"));

}

3.列表类型参数

Dapper允许您使用列表在IN子句中指定多个参数。

var sql = "SELECT * FROM emp WHERE empno in @empno";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

DynamicParameters parameter = new DynamicParameters();

parameter.Add("@param_empno", 7777, DbType.Decimal, ParameterDirection.Input);

parameter.Add("@param_ename", "555", DbType.String, ParameterDirection.Input);

parameter.Add("@result_count", dbType: DbType.Int32, direction: ParameterDirection.Output);

var emps = connection.Query(sql, new { empno = new[] {7777,7778 } }).ToList();

}

4.字符串类型参数

var sql = "SELECT * FROM emp WHERE ename = @ename";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emps = connection.Query(sql,

new { ename = new DbString { Value = "卢俊义", IsFixedLength = false, Length = 9, IsAnsi = true } }).ToList();

}

四、异步

Dapper还使用了Async(异步)方法扩展了IDbConnection接口: ExecuteAsync QueryAsync QueryFirstAsync QueryFirstOrDefaultAsync QuerySingleAsync QuerySingleOrDefaultAsync QueryMultipleAsync

示例:

string sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) Values (@empno,@ename,@job,@hiredate,@sal);";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

// 异步

var affectedRows = connection.ExecuteAsync(sql, new { empno = 7369, ename = "SMITH", job = "SALESMAN", hiredate = "2022-4-1", sal = 9000 });

}

五、Dapper支持事务和范围事务

1.事务

从连接开始一个新事务,并将其传递给事务可选参数。

示例:

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

using (var transaction = connection.BeginTransaction())

{

DynamicParameters parameter = new DynamicParameters();

parameter.Add("@param_empno", 7777, DbType.Decimal, ParameterDirection.Input);

parameter.Add("@param_ename", "555", DbType.String, ParameterDirection.Input);

parameter.Add("@result_count", dbType: DbType.Int32, direction: ParameterDirection.Output);

connection.Execute("sp_ChangeEmpInfo", parameter, commandType: CommandType.StoredProcedure, transaction: transaction);

int rowCount = parameter.Get("@result_count");

transaction.Commit();

}

}

2.范围事务

在开始连接之前开始一个新的范围事务。

示例:

using (var transaction = new TransactionScope())

{

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

DynamicParameters parameter = new DynamicParameters();

parameter.Add("@param_empno", 7777, DbType.Decimal, ParameterDirection.Input);

parameter.Add("@param_ename", "555", DbType.String, ParameterDirection.Input);

parameter.Add("@result_count", dbType: DbType.Int32, direction: ParameterDirection.Output);

connection.Execute("sp_ChangeEmpInfo", parameter, commandType: CommandType.StoredProcedure);

int rowCount = parameter.Get("@result_count");

}

transaction.Complete();

}

六、缓冲

缓冲查询对于一个非常大的查询来减少内存使用情况有一定作用。

string sql = "SELECT * FROM emp";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var emps = connection.Query(sql, buffered: false).ToList();

}

七、存储过程

执行一次存储过程

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql, new { param_empno = 7777, param_ename = "卢俊义123" }, commandType: CommandType.StoredProcedure);

}

执行多次存储过程,为参数数组列表中的每个对象执行一次

string sql = "sp_GetEmpInfo";

using (var connection = BaseRepository.GetMySqlConnection())

{

connection.Open();

var affectedRows = connection.Execute(sql,

new[]

{

new { param_empno = 7777, param_ename = "林冲" },

new { param_empno = 7778, param_ename = "宋江" },

},

commandType: CommandType.StoredProcedure);

}

代码示例下载

总结

以上就是在.net6快速使用Dapper,本文从Dapper的方法使用、参数、事务和存储过程等方法,提供Dapper框架的代码使用示例使我们快速便捷地使用该ROM框架。

posted @   白板号  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示