我可能有三年没怎么碰C#了,目前的工作是在全职搞前端,最近有时间抽空看了一下Asp.net Core,Core版本号都到了5.0了,也越来越好用了,下面将记录一下这几天以来使用Asp.Net Core WebApi+Dapper+Mysql+Redis+Docker的一次开发过程。
## 项目结构
最终项目结构如下,CodeUin.Dapper数据访问层,CodeUin.WebApi应用层,其中涉及到具体业务逻辑的我将直接写在Controllers中,不再做过多分层。CodeUin.Helpers我将存放一些项目的通用帮助类,如果是只涉及到当前层的帮助类将直接在所在层级种的Helpers文件夹中存储即可。
![项目结构](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/23df93b7e7b04b8694e04d62ff8b8d2c~tplv-k3u1fbpfcp-zoom-1.image)
## 安装环境
### MySQL
```cmd
# 下载镜像
docker pull mysql
# 运行
docker run -itd --name 容器名称 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=你的密码 mysql
```
如果正在使用的客户端工具连接MySQL提示1251,这是因为客户端不支持新的加密方式造成的,解决办法如下。
![1251](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3f08e9129cd4415ea585eda8ae80cf4d~tplv-k3u1fbpfcp-zoom-1.image)
```shell
# 查看当前运行的容器
docker ps
# 进入容器
docker exec -it 容器名称 bash
# 访问MySQL
mysql -u root -p
# 查看加密规则
select host,user,plugin,authentication_string from mysql.user;
# 对远程连接进行授权
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
# 更改密码加密规则
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
# 刷新权限
flush privileges;
```
最后,使用MySQL客户端工具进行连接测试,我使用的工具是**Navicat Premium**。
![MySQL](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ee8e17e3b3ea409ab9ceea91d72d16cf~tplv-k3u1fbpfcp-zoom-1.image)
### Redis
```shell
# 下载镜像
docker pull redis
# 运行
docker run -itd -p 6379:6379 redis
```
使用Redis客户端工具进行连接测试,我使用的工具是**Another Redis DeskTop Manager**。
![Redis](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e06302f37a44318b3b2bec0f32c259a~tplv-k3u1fbpfcp-zoom-1.image)
### .NET 环境
服务器我使用的是CentOS 8,使用的NET SDK版本5.0,下面将记录我是如何在CentOS 8中安装.NET SDK和.NET运行时的。
```shell
# 安装SDK
sudo dnf install dotnet-sdk-5.0
# 安装运行时
sudo dnf install aspnetcore-runtime-5.0
```
检查是否安装成功,使用`dotnet --info`命令查看安装信息
![SDK](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d96311d2eba343d3b6ed07e68ffdff77~tplv-k3u1fbpfcp-zoom-1.image)
## 创建项目
下面将实现一个用户的登录注册,和获取用户信息的小功能。
### 数据服务层
该层设计参考了 [玉龙雪山](https://www.cnblogs.com/wangyulong/p/8960972.html) 的架构,我也比较喜欢这种结构,一看结构就知道是要做什么的,简单清晰。
首先,新建一个项目命名为CodeUin.Dapper,只用来提供接口,为业务层服务。
- Entities
- 存放实体类
- IRepository
- 存放仓库接口
- Repository
- 存放仓库接口实现类
- BaseModel
- 实体类的基类,用来存放通用字段
- DataBaseConfig
- 数据访问配置类
- IRepositoryBase
- 存放最基本的仓储接口 增删改查等
- RepositoryBase
- 基本仓储接口的具体实现
![Dapper](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/29418d96c75c43ccb88d25fec932d471~tplv-k3u1fbpfcp-zoom-1.image)
#### 创建BaseModel基类
该类存放在项目的根目录下,主要作用是将数据库实体类中都有的字段独立出来。
```c#
using System;
namespace CodeUin.Dapper
{
/// <summary>
/// 基础实体类
/// </summary>
public class BaseModel
{
/// <summary>
/// 主键Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
}
}
```
#### 创建DataBaseConfig类
该类存放在项目的根目录下,我这里使用的是MySQL,需要安装以下依赖包,如果使用的其他数据库,自行安装对应的依赖包即可。
![依赖](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/59add2791f9540e49940d86c8ffe0e0a~tplv-k3u1fbpfcp-zoom-1.image)
该类具体代码如下:
```c#
using MySql.Data.MySqlClient;
using System.Data;
namespace CodeUin.Dapper
{
public class DataBaseConfig
{
private static string MySqlConnectionString = @"Data Source=数据库地址;Initial Catalog=codeuin;Charset=utf8mb4;User ID=root;Password=数据库密码;";
public static IDbConnection GetMySqlConnection(string sqlConnectionString = null)
{
if (string.IsNullOrWhiteSpace(sqlConnectionString))
{
sqlConnectionString = MySqlConnectionString;
}
IDbConnection conn = new MySqlConnection(sqlConnectionString);
conn.Open();
return conn;
}
}
}
```
#### 创建IRepositoryBase类
该类存放在项目的根目录下,存放常用的仓储接口。
```c#
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace CodeUin.Dapper
{
public interface IRepositoryBase<T>
{
Task<int> Insert(T entity, string insertSql);
Task Update(T entity, string updateSql);
Task Delete(int Id, string deleteSql);
Task<List<T>> Select(string selectSql);
Task<T> Detail(int Id, string detailSql);
}
}
```
#### 创建RepositoryBase类
该类存放在项目的根目录下,是IRepositoryBase类的具体实现。
```c#
using Dapper;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;