.Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储
.Net Core3.0 WebApi 项目框架搭建:目录
SqlSugar介绍
SqlSugar是国人开发者开发的一款基于.NET的ORM框架,是可以运行在.NET 4.+ & .NET CORE的高性能、轻量级 ORM框架,众多.NET框架中最容易使用的数据库访问技术。官网http://www.codeisbug.com/Doc/8
SqlSugar的优点:
1、高性能 ,不夸张的说,去掉Sql在数据库执行的时间,SqlSugar是EF数倍性能,另外在批量操作和一对多查询上也有不错的SQL优化
2、高扩展性 ,支持自定义拉姆达函数解析、扩展数据类型、支持自定义实体特性,外部缓存等
3、稳定性和技术支持, 虽然不是官方ORM, 但在稳定性上也是有着数年用户积累,如果遇到问题可以在GITHUB提出来,会根据紧急度定期解决
4、功能全面,虽然SqlSugar小巧可功能并不逊色于EF框架
5、创新、持续更新 ,向下兼容
创建数据库
这里采用DB First的模式,先新建一个数据库,然后新建一张User表,这里比较简单,记得表字段添加注释说明。

使用代码生成器生成数据库连接文件和实体类
下载地址 :https://github.com/sunkaixuan/SoEasyPlatform
用法非常简单
1、下载项目
2、解压项目
3、点击解决方案打开项目

4、配置连接字符串名称、数据库类型和解决方案名称


5、F5运行该项目

6.生成成功

Repository 和Model层中引入SqlSugar
直接在类库中通过Nuget引入 sqlSugarCore或者通过Install-Package sqlSugarCore安装

删除原来Model层的的User.cs将代码生成器生成的实体放到model层的enity文件夹
using System;
using System.Linq;
using System.Text;
using SqlSugar; namespace Webapi.Core.Model.Enity
{
///<summary>
///用户表
///</summary>
[SugarTable("User")]
public partial class User
{
public User()
{ }
/// <summary>
/// Desc:用户ID
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int UserId { get; set; } /// <summary>
/// Desc:用户名
/// Default:
/// Nullable:True
/// </summary>
public string UserName { get; set; } /// <summary>
/// Desc:年龄
/// Default:
/// Nullable:True
/// </summary>
public int? Age { get; set; } }
}
Repository层新建suger文件夹,将生成的DBConext.cs放置进去,里面已经内置了增删改查等方法,可以删除掉这些方法,后面我们自己使用异步实现,还是很方便的,不过,如果要使用异步,就要异步到底,不然就会阻塞,变成了同步。
using Webapi.Core.Model.Entity;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public class DbContext<T> where T : class, new()
{
public DbContext()
{
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "server=.;uid=sa;pwd=sa123;database=CoreDB",
DbType = DbType.SqlServer,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了 });
//调式代码 用来打印SQL
Db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine(sql + "\r\n" +
Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
Console.WriteLine();
}; }
//注意:不能写成静态的
public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }//用来操作当前表的数据 public SimpleClient<User> UserDb { get { return new SimpleClient<User>(Db); } }//用来处理User表的常用操作 }
这里的ConnectionString是数据库连接字符串,我们可以写在配置文件里面,sugar新建BaseDBConfig.cs
public class BaseDBConfig
{
/// <summary>
/// 数据库连接字符串
/// </summary>
public static string ConnectionString { get; set; } }
修改DbContext的构造函数
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = BaseDBConfig.ConnectionString,
DbType = DbType.SqlServer,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了 });
在 startup.cs 中的 ConfigureServices() 方法中添加
//数据库配置
BaseDBConfig.ConnectionString = Configuration.GetSection("AppSettings:ConnectionString").Value;

设计仓储基类接口——IBaseRepository.cs
IRepository 层中添加Base文件夹,并添加接口 IBaseRepository.cs。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks; namespace Webapi.Core.IRepository.Base
{
/// <summary>
/// 基类接口,其他接口继承该接口
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IBaseRepository<TEntity> where TEntity : class
{
/// <summary>
/// 根据ID查询
/// </summary>
/// <param name="objId"></param>
/// <returns></returns>
Task<TEntity> QueryByID(object objId); /// <summary>
/// 添加
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<bool> Add(TEntity model); /// <summary>
/// 修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<bool> Update(TEntity model); /// <summary>
/// 删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<bool> DeleteByIds(object[] ids); }
}
继承基接口
IRepository 层中,将其他的接口,继承Base,新建IUserRepository.cs,然后将其他所有的方法都继承该基类方法
public interface IUserRepository : IBaseRepositoryy<User>
{ }
对仓储基接口进行实现
Repository 层中,添加Base文件夹,并添加 BaseRepository.cs 基类
public class BaseRepository<TEntity> : DbContext<TEntity>, IBaseRepository<TEntity> where TEntity : class, new()
{
/// <summary>
/// 写入实体数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<bool> Add(TEntity model)
{
var i = await Task.Run(() => Db.Insertable(model).ExecuteReturnBigIdentity());
//返回的i是long类型,这里你可以根据你的业务需要进行处理
return i;
} /// <summary>
/// 根据ID删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<bool> DeleteByIds(object[] ids)
{
var i = await Task.Run(() => Db.Deleteable<TEntity>().In(ids).ExecuteCommand());
return i > ;
} /// <summary>
/// 根据ID查询一条数据
/// </summary>
/// <param name="objId"></param>
/// <returns></returns>
public async Task<TEntity> QueryByID(object objId)
{
return await Task.Run(() => Db.Queryable<TEntity>().InSingle(objId));
} /// <summary>
/// 更新实体数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<bool> Update(TEntity model)
{
//这种方式会以主键为条件
var i = await Task.Run(() => Db.Updateable(model).ExecuteCommand());
return i > ;
}
Repository层新建UserRepository,继承BaseRepository和IUserRepository
public class UserRepository : BaseRepository<User>, IUserRepository
{ }
业务逻辑层基类与基接口
IService 层中添加Base文件夹,并添加接口 IBaseService.cs。
public interface IBaseServices<TEntity> where TEntity : class
{
/// <summary>
/// 根据ID列表删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<bool> DeleteByIds(object[] ids); /// <summary>
/// 根据ID查询
/// </summary>
/// <param name="objId"></param>
/// <returns></returns>
Task<TEntity> QueryByID(object objId); /// <summary>
/// 添加实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<bool> Add(TEntity model); /// <summary>
/// 更新实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns> Task<bool> Update(TEntity model);
}
Service 层中添加Base文件夹,并添加接口 BaseService.cs。并添加 BaseService.cs 基类
public class BaseServices<TEntity> : IBaseServices<TEntity> where TEntity : class, new()
{
public IBaseRepository<TEntity> baseDal = new BaseRepository<TEntity>(); /// <summary>
/// 写入实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<bool> Add(TEntity model)
{
return await baseDal.Add(model);
} /// <summary>
/// 根据ID删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns> public async Task<bool> DeleteByIds(object[] ids)
{
return await baseDal.DeleteByIds(ids);
} /// <summary>
/// 根据ID查询
/// </summary>
/// <param name="objId"></param>
/// <returns></returns>
public async Task<TEntity> QueryByID(object objId)
{
return await baseDal.QueryByID(objId);
} /// <summary>
/// 更新实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<bool> Update(TEntity model)
{
return await baseDal.Update(model);
}
}
IService 层新建IUserService,继承BaseService
public interface IUserService : IBaseService<User>
{ }
Service 层新建IUserService,继承BaseService和IUserService
public class UserService : BaseService<User>, IUserService
{ }
新增接口
User控制器新增接口:
/// <summary>
/// 根据id获取数据
/// </summary>
/// <param name="id">参数id</param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public async Task<IActionResult> GetUser(int id)
{
IUserService userService = new UserService();
User user = await userService.QueryByID(id);
return Ok(user);
} /// <summary>
/// 添加数据
/// </summary>
/// <param name="id">参数id</param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public async Task<IActionResult> Add(User user)
{
IUserService userService = new UserService();
var count = await userService.Add(user);
return Ok(count);
} /// <summary>
/// 更新数据
/// </summary>
/// <param name="id">参数id</param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public async Task<IActionResult> Update(User user)
{
IUserService userService = new UserService();
var sucess = await userService.Update(user);
return Ok(sucess);
} /// <summary>
/// 删除数据
/// </summary>
/// <param name="id">参数id</param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public async Task<IActionResult> Delete(object[] ids)
{
IUserService userService = new UserService();
var sucess = await userService.DeleteByIds(ids);
return Ok(sucess);
}
调试接口
F5运行项目,测试添加接口:

数据库成功添加了数据,因为Id用的是自增,所以是1

测试查询接口:

测试修改接口

如果修改不存在的ID,则删除失败

测试删除接口:

数据已删除

本章Github
https://github.com/huguodong/Webapi.Core/tree/sqlsugar/
.Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储的更多相关文章
- .Net Core3.0 WebApi 项目框架搭建 五:仓储模式
.Net Core3.0 WebApi 项目框架搭建:目录 理论介绍 仓储(Respository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装.其优点: 1)业务层不需要知道它 ...
- .Net Core3.0 WebApi 项目框架搭建:目录
一.目录 .Net Core3.0 WebApi 项目框架搭建 一:实现简单的Resful Api .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger .Net ...
- .Net Core3.0 WebApi 项目框架搭建 一:实现简单的Resful Api
.Net Core3.0 WebApi 项目框架搭建:目录 开发环境 Visual Studio 2019.net core 3.1 创建项目 新建.net core web项目,如果没有安装.net ...
- .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger
.Net Core3.0 WebApi 项目框架搭建:目录 为什么使用Swagger 随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染.后端分离的形态,而且前端技术和后端技 ...
- .Net Core3.0 WebApi 项目框架搭建 三:读取appsettings.json
.Net Core3.0 WebApi 项目框架搭建:目录 appsettings.json 我们在写项目时往往会把一些经常变动的,可能会变动的参数写到配置文件.数据库中等可以存储数据且方便配置的地方 ...
- .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证
.Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...
- 轻量型ORM框架Dapper的使用
在真实的项目开发中,可能有些人比较喜欢写SQL语句,但是对于EF这种ORM框架比较排斥,那么轻量型的Dapper就是一个不错的选择,即让你写sql语句了,有进行了关系对象映射.其实对于EF吧,我说下我 ...
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...
- (三) Angular2项目框架搭建心得
前言: 在哪看到过angular程序员被React程序员鄙视,略显尴尬,确实Angular挺值得被调侃的,在1.*版本存在的几个性能问题,性能优化的"潜规则"贼多,以及从1.*到2 ...
随机推荐
- Pycharm 操作数据库
view--->Tool Buttons,点击Pycharm右侧的Database 1.连接数据库 2.建立一个表,添加数据 通过以上操作把用户名和密码储存到了数据库中 3.连 ...
- 20199326《Linux内核原理与分析》第十一周作业
Shellsock攻击实验 实验背景 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发. Shellshock,又称Bash ...
- NC使用练习之通达OA-2017版本漏洞复现后续
利用上一篇通达OA的漏洞环境,练习NC工具的使用. 步骤: 1.本机启动nc.exe监听端口: 确认端口是否成功监听成功: 2.用冰蝎将nc.exe上传至目标机: 3.用命令行在目标机启动nc.exe ...
- 单源最短路问题--朴素Dijkstra & 堆优化Dijkstra
许久没有写博客,更新一下~ Dijkstra两种典型写法 1. 朴素Dijkstra 时间复杂度O(N^2) 适用:稠密图(点较少,分布密集) #include <cstdi ...
- UVALive 7509 Dome and Steles
三分 #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #d ...
- 01-Vue初学习
1. Vue下载 (1)网址:https://cn.vuejs.org/v2/guide/installation.html (2)点击开发版本,下载完成是一个 Vue.js 2. 使用 (1)创建文 ...
- Android MVP 十分钟入门!
前言 在日常开发APP 的过程中,随着业务的扩展,规模的变化.我们的代码规模也会逐渐变得庞大,每一个类里的代码也会逐渐增多.尤其是Activity和Fragment ,由于Context 的存在,基本 ...
- Nginx重写请求后将url?后的参数去除
2019独角兽企业重金招聘Python工程师标准>>> 使用?结尾 注意,关键点就在于"?"这个尾缀.重定向的目标地址结尾处如果加了?号,则不会再转发传递 ...
- Python爬虫,抓取淘宝商品评论内容!
作为一个资深吃货,网购各种零食是很频繁的,但是能否在浩瀚的商品库中找到合适的东西,就只能参考评论了!今天给大家分享用python做个抓取淘宝商品评论的小爬虫! 思路 我们就拿"德州扒鸡&qu ...
- Linux 查看进程资源--ps、top命令
1,ps命令 ps能够给出当前系统中进程的快照.它能捕获系统在某一事件的进程状态 命令参数: a 显示所有进 ...