.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 ...
随机推荐
- Java中集合的初等案例
我有五个学生,请把这个学生的信息储存到数组中,并遍历数组,获取得到每一个学生信息. 学生:Strdent 成员变量:name,age 构造方法:无参,带参 成员方法:getXxx()/setXxx() ...
- 免费 https 申请步骤,你必须知道
不适用 https 加密的网站,基本上就等于在裸奔. 来,开始开始动手做 我的系统是 CentOS6 第一步:安装Certbot Certbot可以用于管理(申请.更新.配置.撤销和删除等)Let's ...
- Codeforces Round #628 (Div. 2) 题解
人闲桂花落,夜静春山空. 月出惊山鸟,时鸣春涧中.--王维 A. EhAb AnD gCd You are given a positive integer x. Find any such 2 po ...
- (转)对中级 Linux 用户非常有用的 20 个命令
也许你已经发现第一篇文章非常的有用,这篇文章是继对初级Linux用户非常有用的20个命令的一个延伸. 第一篇文章的目的是为新手准备的而这篇文章则是为了Linux的中高级用户.在这里你将学会如何进行自定 ...
- js 函数的多图片懒加载(lazy) 带插件版完整解析
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS实现图片懒加载效果 页面需求 1 ...
- 浅析 JS 中的作用域链
作用域链的形成 在 JS 中每个函数都有自己的执行环境,而每个执行环境都有一个与之对应的变量对象.例如: var a = 2 function fn () { var a = 1 console.lo ...
- 标准库hashlib模块
hashlib模块用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512, MD5 算法(都是基于hash的算法, ...
- MATLAB学习1 之画图函数
ezplot适用条件 "ezplot"命令可以用于显函数.隐函数和参数方程作图. 不同函数的使用格式 显函数y=f(x),ezplot函数的调用格式为ezplot(f, [xmin ...
- JVM调优方法笔记
1.性能工具介绍 jvisualvm jmap jstat jstack/threaddump jprofiler jmeter 2.性能调优4步骤 重现问题 定位问题 模拟问题 解决问题 http: ...
- Damaged Hard Drive and Reinstall System
0 缘由 我是ACER笔记本,电脑从桌子上重摔,之后几天可以正常使用.可是后来看完视频准备退出的时候,发现所有页面已经卡死了,内存占用已经超过了80%,任务管理器没有反应,不得已按了电源键强制关机. ...