.Net使用Dapper框架(快速上手)

Dapper:小型ORM,速度快,支持多数据库,灵活性高,性能高,支持多个.net版本,语法简单,可扩展性强

目录

一、Dapper特点

二、常用方法

1.准备

2. Execute

INSERT语句

UPDATE语句

DELETE语句

有参存储过程

2.Query

查询匿名类型

查询强类型 

查询多映射(一对一) 

 查询多映射(一对多)

3.QueryFirst

First, Single和Default比较

查询匿名类型

查询强类型

4.QueryFirstOrDefault

First, Single和Default比较

查询匿名类型

查询强类型

5.QuerySingle

查询匿名类型

查询强类型

6.QuerySingleOrDefault

查询匿名类型

查询强类型

7.QueryMultiple

QueryMultiple方法

三、参数

1.匿名类型参数

单次执行

多次执行

2.动态类型参数

单次执行

多次执行

3.列表类型参数

4.字符串类型参数

四、异步

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

1.事务

2.范围事务

六、缓冲

七、存储过程

总结


一、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<Emp>(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<Emp, Dept, Emp>(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<decimal, Emp>();

	var emps = connection.Query<Emp,Assignment,Emp>(sql,
		(emp, assignment) =>
		{
			Emp empEntity;

			if (!empAssignment.TryGetValue(emp.empno, out empEntity))
			{
				empEntity = emp;
				empEntity.assignments = new List<Assignment>();
				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<Emp>(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<Emp>(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<Emp>(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<Emp>(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<Emp>().First();
		var assignments = multi.Read<Assignment>().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<int>("@result_count");
}

多次执行

var sql = "sp_ChangeEmpInfo";
var parameters = new List<DynamicParameters>();
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<int>("@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<Emp>(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<Emp>(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<int>("@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<int>("@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框架。

  • 8
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜飞鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值