ABP(ASP.NET Boilerplate Project)快速入门
前言
这两天看了一下ABP,做个简单的学习记录。记录主要有以下内容:
- 从官网创建并下载项目(.net core 3.x + vue)
- 项目在本地成功运行
- 新增实体并映射到数据库
- 完成对新增实体的基本增删改查
ABP官网:https://aspnetboilerplate.com/ Github:https://github.com/aspnetboilerplate
创建项目
进入官网
Get started,选择前后端技术栈,我这里就选.net core 3.x和vue。
填写自己的项目名称,邮箱,然后点create my project就可以下载项目了。
解压文件
运行项目
后端项目
首先运行后端项目,打开/aspnet-core/MyProject.sln
改一下MyProject.Web.Host项目下appsettings.json的数据库连接字符串,如果本地安装了mssql,用windows身份认证,不改也行
数据库默认是使用mssql的,当然也可以改其他数据库。
将MyProject.Web.Host项目设置为启动项,打开程序包管理器控制台,默认项目选择DbContext所在的项目,也就是MyProject.EntityFrameworkCore。执行update-database
数据库已成功创建:
Ctrl+F5,不出意外,浏览器就会看到这个界面:
前端项目
后端项目成功运行了,下面运行一下前端项目,先要确保本机有nodejs环境并安装了vue cli,这个就不介绍了。
/vue目录下打开cmd执行:npm install
install完成后执行:npm run serve
打开浏览器访问http://localhost:8080/,不出意外的话,会看到这个界面:
使用默认用户 admin/123qwe 登录系统:
至此,前后端项目都已成功运行。那么基于abp的二次开发该从何下手呢,最简单的,比如要增加一个数据表,并且完成最基本CRUD该怎么做?
新增实体
实体类需要放在MyProject.Core项目下,我新建一个MyTest文件夹,并新增一个Simple类,随意给2个属性。
我这里继承了abp的Entity类,Entity类有主键ID属性,这个泛型int是指主键的类型,不写默认就是int。abp还有一个比较复杂的FullAuditedEntity类型,继承FullAuditedEntity的话就有创建时间,修改时间,创建人,修改人,软删除等字段。这个看实际情况。
public class Simple : Entity<int>
{
public string Name { get; set; }
public string Details { get; set; }
}
修改MyProject.EntityFrameworkCore项目的/EntityFrameworkCore/MyProjectDbContext:
public class MyProjectDbContext : AbpZeroDbContext<Tenant, Role, User, MyProjectDbContext>
{
/* Define a DbSet for each entity of the application */
public DbSet<Simple> Simples { get; set; }
public MyProjectDbContext(DbContextOptions<MyProjectDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Simple>(p =>
{
p.ToTable("Simples", "test");
p.Property(x => x.Name).IsRequired(true).HasMaxLength(20);
p.Property(x => x.Details).HasMaxLength(100);
});
}
}
然后就可以迁移数据库了,程序包管理器控制台执行:add-migration mytest1
,update-database
刷新数据库,Simples表已生成:
实体的增删改查
进入MyProject.Application项目,新建一个MyTest文件夹
Dto
CreateSimpleDto,新增Simple数据的传输对象,比如ID,创建时间,创建人等字段,就可以省略
public class CreateSimpleDto
{
public string Name { get; set; }
public string Details { get; set; }
}
PagedSimpleResultRequestDto,分页查询对象
public class PagedSimpleResultRequestDto : PagedResultRequestDto
{
/// <summary>
/// 查询关键字
/// </summary>
public string Keyword { get; set; }
}
SimpleDto,这里跟CreateSimpleDto的区别就是继承了EntityDto,多了个ID属性
public class SimpleDto : EntityDto<int>
{
public string Name { get; set; }
public string Details { get; set; }
}
SimpleProfile,用来定义AutoMapper的映射关系清单
public class SimpleProfile : Profile
{
public SimpleProfile()
{
CreateMap<Simple, SimpleDto>();
CreateMap<SimpleDto, Simple>();
CreateMap<CreateSimpleDto, Simple>();
}
}
Service
注意,类名参考abp的规范去命名。
ISimpleAppService,Simple服务接口。我这里继承IAsyncCrudAppService,这个接口中包含了增删改查的基本定义,非常方便。如果不需要的话,也可以继承IApplicationService自己定义
public interface ISimpleAppService : IAsyncCrudAppService<SimpleDto, int, PagedSimpleResultRequestDto, CreateSimpleDto, SimpleDto>
{
}
SimpleAppService,Simple服务,继承包含了增删改查的AsyncCrudAppService类,如果有需要的话可以override这些增删改查方法。也可以继承MyProjectAppServiceBase,自己定义。
public class SimpleAppService : AsyncCrudAppService<Simple, SimpleDto, int, PagedSimpleResultRequestDto, CreateSimpleDto, SimpleDto>, ISimpleAppService
{
public SimpleAppService(IRepository<Simple, int> repository) : base(repository)
{
}
/// <summary>
/// 条件过滤
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
protected override IQueryable<Simple> CreateFilteredQuery(PagedSimpleResultRequestDto input)
{
return Repository.GetAll()
.WhereIf(!input.Keyword.IsNullOrWhiteSpace(), a => a.Name.Contains(input.Keyword));
}
}
接口测试
重新运行项目,不出意外的话,Swagger中就会多出Simple相关的接口。
- Create
- Get
- GetAll
- Update
- Delete
总结
ABP是一个优秀的框架,基于ABP的二次开发肯定会非常高效,但前提是需要熟练掌握ABP,弄清楚他的设计理念以及他的一些实现原理。
以后有时间的话再深入学习一下。文中如果有不妥之处欢迎指正。
- 大话MVP
- AngularJS in Action读书笔记1——扫平一揽子专业术语
- MS Enterprise Library 5.0发布!!
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
- 《Enterprise Library深入解析与灵活应用》博文系列汇总
- 使命必达: 深入剖析WCF的可靠会话[概念篇]
- AngularJS in Action读书笔记2——view和controller的那些事儿
- WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
- 小程序上线“小游戏”,正式引爆3.0社交红利
- 漫谈人工智能机器翻译的前世今生
- 并发与实例上下文模式: WCF服务在不同实例上下文模式下具有怎样的并发表现
- 区块链将变革的五个行业
- WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[上篇]
- AngularJS in Action读书笔记3——走近Services
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 微服务开源框架TARS 之 基础组件
- Gitlab-ci:从零开始的前端自动化部署
- 从 1 到 0 构建博客项目(导读)
- 应该在JavaScript中使用Class吗
- Go语言小书 | 关于编译和语法
- Go语言小书 | 小试牛刀,从hello world开始
- 3分钟短文 | Laravel 中间件传递数据到控制器
- 3分钟短文 | Laravel 表单验证数组的数据
- 3分钟短文:Laravel 编程中优雅地添加定义常量
- 极客算法训练笔记(四),栈和队列,从实际应用看数据结构
- 微博爬虫出错居然还和网络运营商有关
- 8.深入k8s:资源控制Qos和eviction及其源码分析
- 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知
- CNN不用乘法? AdderNet和DeepShift论文理解
- 动手构建地铁关系网,实现最短路径查询