Dapper异步使用学习 Dapper已经赢得了C#轻量级ORM的王者称号,但却被很多人认为是一款用于.Net环境的简单的对象映射器。当人们希望自己编写具有最佳性能的SQL查询时,他们会更喜欢Dapper。
Dapper已经赢得了C#轻量级ORM的王者称号,但却被很多人认为是一款用于.Net环境的简单的对象映射器。当人们希望自己编写具有最佳性能的SQL查询时,他们会更喜欢Dapper。Dapper是100%安全的!你可以像往常一样使用参数化查询,不用担心被SQL注入的问题,此外Dapper还支持事务操作,第三方扩展的Dapper. Plus 还支持批量操作!而且已经支持异步了,最近我就尝试了使用Dapper的异步方法来操作数据库,所以在此做个分享,也加深一遍理解。
尤其是对三表Join操作的splitOn参数的理解,以及事务操作的使用,说实话,文档里有很多细节并未详细说明,只能靠你自己去实践,模拟业务场景去实验是最佳的学习方式,很多技术内部细节都能靠尝试和实验反推出来。
1. 数据库创建表
学习Dapper首先要先准备好一个数据库,这里我选择MySQL,Mysql比较常用,基本上生产环境普遍都是Mysql,我也曾尝试安装过Sql Server 2017 但是实在是太大了,作为开发者,它远不如Mysql更轻量,更易安装使用。先建一个数据库,创建三张表,角色表,用户表,部门表,三张表有关联关系,SQL语句如下:
-- 部门表 CREATE TABLE `Departments` ( `ID` int(0) NOT NULL AUTO_INCREMENT, `DepartmentName` varchar(50) `PDepartmentID` int(0) NOT NULL, PRIMARY KEY (`ID`) USING BTREE ) -- 角色表 CREATE TABLE `Roles` ( `ID` int(0) NOT NULL AUTO_INCREMENT, `RoleName` varchar(20) PRIMARY KEY (`ID`) USING BTREE ) -- 用户表 CREATE TABLE `Users` ( `ID` int(0) NOT NULL AUTO_INCREMENT, `DepartmentID` int(0) DEFAULT NULL, `Name` varchar(50) `Password` varchar(50) `RoleID` int(0) DEFAULT NULL, `UserName` varchar(50) PRIMARY KEY (`ID`) USING BTREE )
2. 实体类创建
使用过ORM框架的童鞋们都知道,如果使用ORM,必要条件就是要创建与表各字段关系对应的实体类,Object-Relationl Mapping,它的作用就是在关系型数据库和对象之间作一个映射。
/// <summary> /// 角色 /// </summary> public class Roles { public int ID { get; set; } public string RoleName { get; set; } } /// <summary> /// 部门 /// </summary> public class Departments { public int ID { get; set; } public string DepartmentName { get; set; } public int PDepartmentID { get; set; } } /// <summary> /// 用户 /// </summary> public class Users { public int ID { get; set; } public int DepartmentID { get; set; } public string Name { get; set; } public string Password { get; set; } public int RoleID { get; set; } public string UserName { get; set; } } /// <summary> /// 用户角色综合 /// </summary> public class UsersAndRole { public int ID { get; set; } public string Name { get; set; } public string Password { get; set; } public string UserName { get; set; } public string RoleName { get; set; } public string DepartmentName { get; set; } public Roles Role { get; set; } }
3. 执行插入/修改/删除
插入,删除和修改操作,基本相同,所以这里只写了插入操作的实例代码。
// 插入单个对象
// 插入单个对象 public static async Task<int> InsertRoleAsync() { using (IDbConnection connection = new MySqlConnection(connectionString)) { return await connection.ExecuteAsync("insert into Roles(RoleName) values(@RoleName)", new Roles() { RoleName = "管理员" }); } } // 插入多个对象 public static async Task<int> InsertBatchRoleAsync() { using (IDbConnection connection = new MySqlConnection(connectionString)) { return await connection.ExecuteAsync("insert into Roles(RoleName) values(@RoleName)", new List<Roles>() { new Roles(){ RoleName="a"}, new Roles(){ RoleName="b"}, new Roles(){ RoleName="c"}, }); } }
4. 基本查询操作
基本查询语句操作包括,无参数查询,有参数查询,In语句查询,及 多语句执行查询,这里均采用异步的方法。
/// <summary> /// 无参查询所有数据 /// </summary> /// <returns></returns> public static List<Roles> QueryRoles() { using (IDbConnection connection = new MySqlConnection(connectionString)) { return connection.QueryAsync<Roles>("select * from Roles").Result.ToList(); } } /// <summary> /// 查询指定数据 /// </summary> /// <param name="person"></param> /// <returns></returns> public static Roles QueryRolesByRoleName(string roleName) { using (IDbConnection connection = new MySqlConnection(connectionString)) { return connection.QueryAsync<Roles>("select * from Roles where RoleName=@RoleName", new { RoleName= roleName }).Result.SingleOrDefault(); } } /// <summary> /// In语句操作 /// </summary> public static List<Roles> QueryIn() { using (IDbConnection connection = new MySqlConnection(connectionString)) { var sql = "select * from Roles where id in @ids"; return connection.QueryAsync<Roles>(sql, new { ids = new int[2] { 1, 2 }, }).Result.ToList(); } } /// <summary> /// 多语句操作 /// </summary> public static void QueryUsersAndRolesMultiple() { using (IDbConnection connection = new MySqlConnection(connectionString)) { var sql = "select * from Users; select * from Roles"; var multiReader = connection.QueryMultiple(sql); var roleList = multiReader.Read<Roles>(); var userList = multiReader.Read<Users>(); Console.WriteLine(JsonConvert.SerializeObject(roleList)); Console.WriteLine(JsonConvert.SerializeObject(userList)); multiReader.Dispose(); } }
5. Join内联接查询
Join内联接查询,这个实例是我特意设计出来的,采用三个关联表Join联合查询出用户的详细数据,根据字段的顺序,我将splitOn分割参数设置为"Name"字段,因为只要在Name字段时才能查出所有字段的值,Dapper扫描字段是按照从右向左的顺序扫的,所以尽量选择字段顺序最开始的除了ID之外的字段作为分割参数。
记住SQL语句中字段的顺序:u.id as ID,Name,Password,UserName,RoleName,DepartmentName
/// <summary> /// Join查询 /// </summary> /// <param name="UserName"></param> /// <returns></returns> public static UsersAndRole QueryAsyncJoin(string UserName) { using (IDbConnection connection = new MySqlConnection(connectionString)) { var sql = @"SELECT u.id as ID,Name,Password,UserName,RoleName,DepartmentName FROM Users u Join Roles r on u.RoleID=r.ID Join Departments d on u.DepartmentID=d.ID WHERE u.UserName=@userName "; var result = connection.QueryAsync<Roles, UsersAndRole, UsersAndRole>(sql, (role,urd) => { urd.Role = role; return urd; },new { userName = UserName }, splitOn: "Name"); return (UsersAndRole)result.Result.FirstOrDefault(); } }
执行方法
var result = QueryAsyncJoin("大林"); Console.WriteLine(JsonConvert.SerializeObject(result));
详细讲解一下,为了方便展示,我将查询结果Json序列化了,方便观察,我们先看按Name字段分割时的运行结果截图,可以看到所有字段值都查询出来了
如果按Password字段分割呢?你看显然,Name值就空了
再看按UserName分割,然后发现Name,Password都空了,你看,规律就找到了吧。
6. 事务操作
事务操作分为Dapper的内部事务方法,和.Net 基础库自带的事务方法。
/// <summary> /// Dapper事务 /// </summary> /// <returns></returns> public static int TransactionDapper() { int effaffectedRows = -1; using (IDbConnection connection = new MySqlConnection(connectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { effaffectedRows = connection.Execute("insert into Roles(RoleName) values(@RoleName)", new Roles() { RoleName = "管理员" }, transaction: transaction); transaction.Commit(); } } return effaffectedRows; } /// <summary> /// 系统事务 /// </summary> /// <returns></returns> public static int TransactionSystem() { int effaffectedRows = -1; using (var transaction = new TransactionScope()) { using (IDbConnection connection = new MySqlConnection(connectionString)) { connection.Open(); effaffectedRows = connection.Execute("insert into Roles(RoleName) values(@RoleName)", new Roles() { RoleName = "管理员" }); } transaction.Complete(); return effaffectedRows; } }
7. Dapper 官方文档链接
https://dapper-tutorial.net/dapper
————————————————
版权声明:本文为CSDN博主「卷儿哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/DahlinSky/article/details/104766612
文章末尾固定信息

评论