ASP.NET Core模块化前后端分离快速开发框架介绍之3、数据访问模块介绍
源码
GitHub:https://github.com/iamoldli/NetModular
演示地址
地址:https://nm.iamoldli.com
账户:admin
密码:admin
前端框架演示地址(临时)
地址:http://nm.demo.iamoldli.com/index.html
账户:admin
密码:admin
目录
1、开篇
2、快速创建一个业务模块
3、数据访问模块介绍
4、模块化实现思路
简介
NetModular
的数据访问模块是基于 Dapper 扩展的轻量级的ORM,它本身是完全独立的,可以在任何项目中直接使用。在NetModular
中也提供了扩展,能够完美的与模块化集成在一起。
支持的功能
- [x] 支持SqlServer、MySql、SQLite数据库
- [x] 基础的CRUD方法
- [x] 批量添加、删除、修改
- [x] 修改指定列
- [x] Lamdba表达式支持
- [x] 多表连接查询
- [x] 分页查询
- [x] 分组查询
- [x] 仓储模式
- [x] 工作单元
- [x] 自定义表名、列名
- [x] 支持同步/异步方法
使用方法
NetModular
本身已经做好了集成,所以业务模块中,可以直接写代码,不用考虑注入的问题,如果想要了解它的集成逻辑的,可以查看Data.AspNetCore
库
Node: 数据库上下文、仓储和工作单元的注入方式采用的是
Scoped
1、添加数据库上下文
数据库上下文需要继承DbContext
public class MallDbContext : DbContext
{
public MallDbContext(IDbContextOptions options) : base(options)
{
}
}
2、创建实体
实体需要继承IEntity
接口,在NetModular
中,已经提供了几个通用的实体基类,并且内部已经实现了对应的功能,比如EntityBase
:
public class EntityBase<TKey> : Entity<TKey>
{
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建人
/// </summary>
public Guid CreatedBy { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime ModifiedTime { get; set; } = DateTime.Now;
/// <summary>
/// 修改人
/// </summary>
public Guid ModifiedBy { get; set; }
/// <summary>
/// 创建人名称
/// </summary>
[Ignore]
public string Creator { get; set; }
/// <summary>
/// 修改人
/// </summary>
[Ignore]
public string Modifier { get; set; }
}
可以看到 EntityBase
已经包含了CreatedTime
,CreatedBy
,ModifiedTime
,ModifiedBy
这四个实体属性,通过实体继承了EntityBase
,那么该实体也包含了这个属性,同时NetModular
内部已经实现了在添加,修改时,自动设置对应的创建人和修改人编号,所以你不需要你去考虑这些事情了。
另外还有包含软删除功能的EntityWithSoftDelete
以及包含上面两个实体功能的EntityBaseWithSoftDelete
两个实体,这些都已经封装好了,可以直接用。
Node: 上面的三个实体基类都会继承自
Entity
,该实体包含了一个主键Id
,主键类型支持Guid(默认)、Int、Long三种类型。
可以通过Table特性,设置实体对应的表名称
以下是一个产品的实体示例:
[Table("Product")]
public partial class ProductEntity : EntityBase
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 价格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 库存
/// </summary>
public int Store { get; set; }
/// <summary>
/// 状态
/// </summary>
public ProductStatus Status { get; set; }
}
实体扩展类:
Node: 实体扩展类中的属性,必须添加Ignore
特性,否则属性会被当成表的列处理。
public partial class ProductEntity
{
/// <summary>
/// sku列表
/// </summary>
[Ignore]
public List<Guid> Skus { get; set; }
}
3、添加仓储接口
仓储接口必须继承IRepository<>
接口
/// <summary>
/// 产品仓储接口
/// </summary>
public interface IProductRepository : IRepository<ProductEntity>
{
/// <summary>
/// 查询
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
Task<IList<ProductEntity>> Query(ProductQueryModel model);
}
4、添加查询模型
查询模型包含查询条件,需要继承QueryModel
类,该类包含了分页相关的信息
public class ProductQueryModel : QueryModel
{
public string Title { get; set; }
}
5、添加仓储实现
仓储实现需要继承抽象仓储RepositoryAbstract<>
,不同数据库的仓储实现,需要放到不同的目录中。因为不同的数据库难免会有一些查询,所以我们采用先实现一种数据库的实现,然后其它数据实现直接继承它,对于有查询的方法,采用覆写的方式实现。
public class ProductRepository : RepositoryAbstract<ProductEntity>, IProductRepository
{
public ProductRepository(IDbContext context) : base(context)
{
}
public async Task<IList<ProductEntity>> Query(ProductQueryModel model)
{
//分页
var paging = model.Paging();
var query = Db.Find();
query.WhereIf(model.Title.NotNull(), m => m.Title.Contains(model.Title));
//设置默认排序
if (!paging.OrderBy.Any())
{
query.OrderByDescending(m => m.Id);
}
var list = await query.PaginationAsync(paging);
model.TotalCount = paging.TotalCount;
return list;
}
}
上面的例子是一个最简单的分页查询,到此数据访问的代码就写完了,剩下的就是在服务层调用就行了。
其它用法说明
1、CRUD
基础的CRUD在RepositoryAbstract
中已经实现了,所以可以直接在服务中调用
新增
_repository.AddAsync(entity);
批量新增
_repository.AddAsync(entities);
删除
_repository.DeleteAsync(id);
软删除
_repository.SoftDeleteAsync(id);
修改
_repository.UpdateAsync(entity);
获取
_repository.GetAsync(id);
获取所有
_repository.GetAllAsync()
是否存在
_repository.ExistsAsync(m => m.Title.Contains("test"))
批量修改
/// <summary>
/// 批量修改状态
/// </summary>
/// <param name="ids"></param>
/// <param name="status"></param>
/// <returns></returns>
public Task<bool> UpdateStatus(List<Guid> ids, ProductStatus status)
{
return Db.Find(m => ids.Contains(m.Id)).UpdateAsync(m => new ProductEntity { Status = status });
}
批量删除
/// <summary>
/// 批量删除
/// </summary>
/// <param name="title"></param>
/// <returns></returns>
public Task<bool> Delete(string title)
{
return Db.Find(m => m.Title.Contains(title)).DeleteAsync();
}
表连接查询
public async Task<IList<ProductEntity>> Query(ProductQueryModel model)
{
//分页
var paging = model.Paging();
var query = Db.Find();
query.WhereIf(model.Title.NotNull(), m => m.Title.Contains(model.Title));
//设置默认排序
if (!paging.OrderBy.Any())
{
query.OrderByDescending(m => m.Id);
}
var list = await query.LeftJoin<AccountEntity>((x, y) => x.CreatedBy == y.Id)
.Select((x, y) => new { x, Creator = y.Name })
.PaginationAsync(paging);
model.TotalCount = paging.TotalCount;
return list;
}
分组查询
Db.Find().GroupBy(m => new { m.Status }).Select(m => new { m.Key.Status, Count = m.Count() });
工作单元
工作单元在服务中注入使用
private readonly IUnitOfWork _uow;
public ArticleService(IUnitOfWork<MalDbContext> uow)
{
_uow = uow;
}
然后通过BeginTransaction
方法开启事务,Commit
方法提交事务,Rollback
方法回滚事务
_uow.BeginTransaction();
var result = await _accountRepository.AddAsync(account);
if (result)
{
if (model.Roles != null && model.Roles.Any())
{
var accountRoleList = model.Roles.Select(m => new AccountRoleEntity { AccountId = account.Id, RoleId = m }).ToList();
if (await _accountRoleRepository.AddAsync(accountRoleList))
{
_uow.Commit();
return ResultModel.Success();
}
}
else
{
_uow.Commit();
return ResultModel.Success();
}
}
好了,数据库访问的用法大致就是这样~
ASP.NET Core模块化前后端分离快速开发框架介绍之3、数据访问模块介绍的更多相关文章
- ASP.NET Core模块化前后端分离快速开发框架介绍之4、模块化实现思路
源码 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com 账户:admin 密码:admin 前 ...
- ASP.NET Core模块化前后端分离快速开发框架介绍之2、快速创建一个业务模块
源码地址 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com 账户:admin 密码:admin ...
- ASP.NET Core模块化前后端分离快速开发框架介绍之1、开篇
源码地址 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com 账户:admin 密码:admin ...
- .Net Core+Vue.js模块化前后端分离快速开发框架NetModular更新日志(2019-12-08)
源码 GitHub:https://github.com/iamoldli/NetModular 码云:https://gitee.com/laoli/NetModular 欢迎star~ 文档 ht ...
- .NET Core前后端分离快速开发框架(Core.3.0+AntdVue)
.NET Core前后端分离快速开发框架(Core.3.0+AntdVue) 目录 引言 简介 环境搭建 开发环境要求 基础数据库构建 数据库设计规范 运行 使用教程 全局配置 快速开发 管理员登录 ...
- [转].NET Core前后端分离快速开发框架(Core.3.0+AntdVue)
[转].NET Core前后端分离快速开发框架(Core.3.0+AntdVue) 目录 引言 简介 环境搭建 开发环境要求 基础数据库构建 数据库设计规范 运行 使用教程 全局配置 快速开发 管理员 ...
- .Net Core与Vue.js模块化前后端分离快速开发解决方案(NetModular)
NetModular是什么? NetModular不仅仅是一个框架,它也是一整套的模块化与前后端分离的快速开发的解决方案,目标是致力于开箱即用,让开发人员完全专注于业务开发,不需要关心底层封装和实现. ...
- 前后端分离后API交互如何保证数据安全性
前后端分离后API交互如何保证数据安全性? 一.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC ...
- 优秀开源平台,前后端分离快速开发平台,一站式多端开发(PC+APP)
JNPF平台架构介绍 JNPF快速开发平台采用前后端分离技术.采用B/S架构开发,形成一站式开发多端(APP+PC)使用. PC端版本介绍 第一个当然是当下热门的.net core了,运行环境为Vis ...
随机推荐
- Excel2010如何实现隔行设置背景色
当Excel表格中的数据很多,很有可能会出现看错行的现象,为防止看错行,可以隔行设置背景色.可以通过套用表格格式或者条件格式来达到隔行变色的效果 方法一:通过套用表格格式 1.选中要处理的单元格或者列 ...
- notepad++的tab设置为4个空格
设置--首选项--语言--制表符设置--(勾选上)替换为空格
- c/c++技巧总结
1.bzero().memset()初始化结构体. 2.求结构体分量在结构体中地址偏移量 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) ...
- pat1079. Total Sales of Supply Chain (25)
1079. Total Sales of Supply Chain (25) 时间限制 250 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHE ...
- Mybatis的小计
1连接池 一 我的错误想法 poolMaximumIdleConnections 最大活跃连接数 poolMaximumActiveConnections 最大空闲连接数 我一直以为 空闲是一直存在的 ...
- WPF使用Aspose.Words导出Word文档
一.创建Word文档模板 分析需要导出的word文档,将固定的内容和由程序生成的内容分开; 创建一个word(例如:Template.doc)文档,将固定的内容按照一定的格式写入当前文档中; 打开Te ...
- C 碎片五 数组
构造类型数据是有基本类型数据按照一定规则组成的.数组,结构体,共用体都属于构造类型的数据.数组是有序数据的集合,C语言数组中的每一个元素都属于同一个数据类型,用数组名和下标来唯一确定数组中的元素. 一 ...
- 移植mavlink到stm32详细教程,后面附快速移植方法
一:准备材料: mavlink源码 stm32串口程序 1.mavlink源码: a.进入mavlink官网(http://qgroundcontrol.org/mavlink/s ...
- 快速获取雪碧图的图标样式插件 - gulp-css-spriter教程
如何快速把合成好的雪碧图,快速获取图标的样式呢? 用gulp-css-spriter很简单. 第一步: 在某个文件夹用shitf+鼠标右键 第二步: npm install gulp-css-spri ...
- PHP函数:mysql_fetch_assoc指针重置
本文目前主要讨论mysql_fetch_assoc“指针”如何重置的问题 要了解mysql_fetch_assoc,先看看它与mysql_fetch_row和mysql_fetch_array的关系. ...