从零开始搭建ABP框架(Asp .Net Boilerplate)+Oracle(11 g)

时间:2021-09-07
本文章向大家介绍从零开始搭建ABP框架(Asp .Net Boilerplate)+Oracle(11 g),主要包括从零开始搭建ABP框架(Asp .Net Boilerplate)+Oracle(11 g)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

声明:该博客最早发布于2021-05-25 17:38:39在CSDN论坛,均为本人原创。
原链接:https://blog.csdn.net/m0_37752065/article/details/117260958

一、总体框架介绍

注意:VS2019版本必须在16.9.4以上,并且安装了.NET 5 SDK和运行时!!

事前准备:先前往:https://aspnetboilerplate.com/Templates 生成项目解决方案模板,注意生成时不要勾选Include login, register, user, role and tenant management pages.复选框,,Target Version要选择v5.x,TargetFramework默认.NET5(Cross Platform),输入项目名字和验证码点击生成并下载。

1、公司名/作者名字.项目名.Core 层

目录构成:
公司名/作者名字.项目名.Core
├─ 项目名Consts.cs	---Abp默认生成,Abp项目常量类,主要存放常用的常量,如数据库连接字符串名
├─ 项目名CoreModule.cs  ---Abp模块类,主要管理Core层的初始化工作
├─ Configuration  ---Abp配置
│    └─ AppConfigurations.cs   
├─ Localization
│    ├─ 项目名LocalizationConfigurer.cs
│    └─ SourceFiles
│           ├─ 项目名-tr.json
│           └─ 项目名.json
├─ 公司名/作者名字.项目名.Core.csproj
├─ Properties
│    └─ AssemblyInfo.cs
├─ Web
│    └─ WebContentFolderHelper.cs
需引用的Nuget包:
Abp(v6.3.0) Abp.AutoMapper(v6.3.0) Microsoft.Extensions.Configuration.EnvironmentVariables(v5.0.0)

2、公司名/作者名.项目名.Application 层

目录构成:
公司名/作者名.项目名.Application
├─ 项目名AppServiceBase.cs
├─ 项目名ApplicationModule.cs
├─ 公司名/作者名.项目名.Application.csproj
├─ Properties
│    └─ AssemblyInfo.cs
需引用的Nuget包:
Abp.AutoMapper(v6.3.0) Abp.EntityFrameworkCore(v6.3.0)

3、公司名/作者名.项目名.EntityFrameworkCore 层

目录结构:
公司名/作者名.项目名.EntityFrameworkCore
├─ EntityFrameworkCore
│    ├─ 项目名DbContext.cs
│    ├─ 项目名DbContextFactory.cs
│    ├─ 项目名EntityFrameworkCoreModule.cs
│    └─ DbContextOptionsConfigurer.cs
├─ 公司名/作者名.项目名.EntityFrameworkCore.csproj
├─ Properties
│    └─ AssemblyInfo.cs
需引用的Nuget包:
Abp.EntityFrameworkCore(v6.3.0) Oracle.EntityFrameworkCore(v5.21.1)

4、公司名/作者名.项目名.Web 层

目录结构
公司名/作者名.项目名.Web
├─ .bowerrc
├─ App_Data
│    └─ Logs
│           └─ Logs.txt
├─ Controllers
│    ├─ 项目名ControllerBase.cs
│    ├─ ErrorController.cs
│    ├─ HomeController.cs
│    ├─ LayoutController.cs
├─ 公司名/作者名.项目名.Web.csproj
├─ 公司名/作者名.项目名.Web.csproj.user
├─ Project_Readme.html
├─ Properties
│    └─ launchSettings.json
├─ Startup
│    ├─ 项目名NavigationProvider.cs
│    ├─ 项目名WebModule.cs
│    ├─ PageNames.cs
│    ├─ Program.cs
│    └─ Startup.cs
├─ Utils
│    └─ UrlHelper.cs
├─ Views
│    ├─ 项目名RazorPage.cs
│    ├─ Home
│    │    ├─ About.cshtml
│    │    └─ Index.cshtml
│    ├─ Shared
│    │    ├─ Components
│    │    ├─ Error.cshtml
│    │    └─ _Layout.cshtml
│    ├─ _ViewImports.cshtml
│    └─ _ViewStart.cshtml
├─ app.config
├─ appsettings.json	---数据库连接字符串配置文件
├─ bower.json
├─ bundleconfig.json
├─ compilerconfig.json
├─ compilerconfig.json.defaults
├─ log4net.Production.config
├─ log4net.config
├─ web.config
└─ wwwroot
       ├─ css
       │    ├─ main.css
       │    ├─ main.less
       │    └─ main.min.css
       ├─ js
       │    └─ views
       ├─ lib
       │    ├─ abp-web-resources
       │    ├─ blockUI
       │    ├─ bootstrap
       │    ├─ bootstrap-paper
       │    ├─ famfamfam-flags
       │    ├─ font-awesome
       │    ├─ jquery
       │    ├─ jquery-validation
       │    ├─ json2
       │    ├─ moment
       │    ├─ spin.js
       │    ├─ sweetalert
       │    └─ toastr
       └─ view-resources
              └─ Views
需要引用的Nuget包:
Abp.AspNetCore(v6.3.0) Abp.Castle.Log4Net(v6.3.0) Castle.Core(v4.4.1) Castle.LoggingFacility.MsLogging(v3.1.0) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore(v5.0.0) Microsoft.EntityFrameworkCore.Analyzers(v5.0.6) Microsoft.EntityFrameworkCore.Tools(v5.0.6) Microsoft.Extensions.Logging(v5.0.0) Microsoft.Extensions.Options.ConfigurationExtensions(v5.0.0) Microsoft.VisualStudio.Web.CodeGeneration.Design(v5.0.2) Oracle.EntityFrameworkCore(v5.21.1) Swashbuckle.AspNetCore(v5.0.0) System.Net.NameResolution(v4.3.0) System.Net.Primitives(v4.3.1)

二、准备工作

1、使用VS2019打开网站生成的解决方案,先移除Tests文件夹,因为不需要!

2、选择项目解决方案,鼠标点击右键,选择“还原Nuget包(R)”。

3、还原完Nuget包之后,将EntityFrameworkCore层里的Microsoft.EntityFramework.SqlServer、Microsoft.EntityFramework.SqlServer.Design包移除。

4、新增Oracle.EntityFrameworkCore包,具体版本号参照上面的第一部分里第三小节。

5、修改EntityFrameworkCore层里的DbContextOptionsConfigurer.cs,将UseSqlServer改为UseOracle。

6、修改Web层里的appsettings.json,把Default里的数据库连接字符串改成Oracle的(具体字符串格式可以百度)

7、引用包时如遇到版本无法降级等情况,先把对应的包卸载,因为有些包已经包含了对应已有的程序集会产生冲突或降级失败等情况发生。

以上工作完成后,接下来正式开始实现单表的增删查改!

三、教程开始

1、新建实体类,User

1.1、展开Core层,右键Core新建文件夹,我们将它命名为User,示例如图:

1.2、右键User文件夹,选择新建类,并把名字命名为TEST_USER。(类名字最好建议对应数据库里数据表的名字,更利于后期的维护!)

1.3、我们在这里定义三个字段,注意该类要继承Abp框架里封装好的Entity,否则依赖注入仓储时会报错!完整代码如下:

using Abp.AutoMapper;
using Abp.Domain.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//注意:所有实体字段都需要有virtual修饰符
namespace Oracle.AbpProject.User
{
    /// <summary>
    /// 用户信息实体类
    /// </summary>
    //必须加Table特性,特别是在实体类名字与数据表名字不一致的情况下,告诉Abp当前实体类是指向哪个数据表的
    [Table("TEST_USER")]
    public class TEST_USER : Entity  //所有要通过仓储实现CRUD的实体类都必须继承自Entity
    {
//由于Entity内置了一个Id属性,因此如果数据库存在类似或相同的ID字段就需要加上[Column]特性用来并重新指向数据库里的字段
        [Column("ID")]	
        public override int Id { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public virtual string NAME { get; set; }
        /// <summary>
        /// 年龄
        /// </summary>
        public virtual int AGE { get; set; }
    }
}

1.4、上面的步骤完成后,要记得前往EntityFrameworkCore层里的DbContext.cs里新增如下代码:

public virtual DbSet<TEST_USER> User { get; set; }

2、新建应用服务类,UserAppService

2.1、展开Application层,并右键该层在弹出的菜单中选择新建文件夹,把新文件夹命名为User。

2.2、在Application层的User文件里右键新建接口,IUserAppService,并且在里面定义增删查改接口,代码如下:

using Abp.Application.Services;
using Oracle.AbpProject.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Oracle.AbpProject
{
    //该接口类需要继承自Abp内置的IApplicationService,同时告诉Abp当前的接口类需要实现应用服务
    //对于需要频繁读取的接口,例如获取列表等建议用Task异步线程方式去请求
    public interface IUserAppService:IApplicationService
    {
        Task AddUser(TEST_USER user);

        Task<List<TEST_USER>> UserList();

        Task DelUser(TEST_USER user);

        Task UpdUser(TEST_USER user);
    }
}

2.3、在新建一个接口实现类,UserAppService,并且继承AbpProjectAppServiceBase和IUserAppService,实现刚才定义的增删查改接口,代码如下:

namespace Oracle.AbpProject
{
    //AbpProjectAppServiceBase,从这个文件不难看出这个文件是Abp默认帮我们当前项目生成的一个应用服务基础类,同时也是实现本地化的一部分,它派生自AppService,而跳转到它的实现,我们会发现它继承了IAppService,所以重要的一部分
    public class UserAppService: AbpProjectAppServiceBase,IUserAppService
    {
        private readonly IRepository<TEST_USER> userRepository;

        public UserAppService(IRepository<TEST_USER> userRepository)
        {
            this.userRepository = userRepository;
        }

        public async Task AddUser(TEST_USER user)
        {
             //业务逻辑
        }

        public async Task<List<TEST_USER>> UserList()
        {
             //业务逻辑
        }

        public async Task DelUser(TEST_USER user)
        {
             //业务逻辑
        }

        public async Task UpdUser(TEST_USER user)
        {
            //业务逻辑
        }
    }

3、新建API接口,UserController

3.1、展开Web层里的Controllers文件夹,右键新建控制器,选择WebAPI控制器,操作如图:

3.2、新建完成后,双击打开UserController.cs文件,并写入如下代码:

namespace Oracle.AbpProject.Web.Controllers
{
    //因为Abp的.NET5版本是基于MVC而不是API的,因此需要手动去声明当前API的路由,否则Swagger无法查找
    [Route("api/[controller]/[Action]")] 
    [ApiController] //声明告诉Swagger,当前控制器是以API形式展现调用的
    //所有新建的Controller都需要继承自Abp的ControllerBase,这既是约定规范也是为了让Abp实现统一管理所有接口
    //AbpProjectControllerBase派生自AbpController,一个Abp内置的Controller函数,同时也基于原生Controller
    public class UserController : AbpProjectControllerBase
    {
        //必须要加ReadOnly,否则会报错,因为Abp默认开启了依赖注入
        private readonly IUserAppService userAppService;

        public UserController(IUserAppService userAppService)
        {
            this.userAppService = userAppService;
        }

        [HttpPost]
        public Task AddUser([FromBody]TEST_USER user)
        {
            return this.userAppService.AddUser(user);
        }

        [HttpGet]
        public Task<List<TEST_USER>> UserList()
        {
            return this.userAppService.UserList();
        }

        [HttpDelete]
        public Task DelUser([FromBody] TEST_USER user)
        {
            return this.userAppService.DelUser(user);
        }

        [HttpPost]
        public Task UpdUser([FromBody]TEST_USER user) 
        {
            return this.userAppService.UpdUser(user);
        }

    }

四、集成SwaggerUI文档教程

1、引入Nuget包,如按照上面第一节已引用包则可忽略当前步骤:

2、设置并初始化Swagger文档。

2.1、展开Web层找到Starup文件夹里的Starup.cs文件,在ConfigureServices方法体里加入如下代码:

using Microsoft.OpenApi.Models;

// 添加Swagger
services.AddSwaggerGen(c =>
{
  c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oracle.MyAbpProject Demo", Version = "v1" });
});
services.AddControllers();

注意:由于Abp默认给所有接口开启了JWT验证,因此在没有Token的前提下请求是会报错的,因此我们暂时注释掉如下代码:

options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());

2.2、在Configure方法体里加入如下代码:

// 添加Swagger有关中间件
app.UseSwagger();
app.UseSwaggerUI(c =>
{
   c.SwaggerEndpoint("/swagger/v1/swagger.json", "Oracle.MyAbpProject Demo v1");
});

为防止调试报错时更直观地显示错误提示,我们可以在WebModule中的PreInitialize方法体中加入如下代码:

Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;

注意:Oracle数据库运行的数据事务隔离级别为ReadCommitted,详细原因可以点击链接查看。因此我们需要加上如下代码:

Configuration.UnitOfWork.IsolationLevel = IsolationLevel.ReadCommitted;
Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);

2.3、预览效果展示:

lize方法体中加入如下代码:

Configuration.Modules.AbpWebCommon().SendAllExceptionsToClients = true;

注意:Oracle数据库运行的数据事务隔离级别为ReadCommitted,详细原因可以点击链接查看。因此我们需要加上如下代码:

Configuration.UnitOfWork.IsolationLevel = IsolationLevel.ReadCommitted;
Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);

2.3、预览效果展示:

五、知识扩展

为了提升调试开发效率,我们还可以把项目的启动默认页改成Swagger文档主页,具体方法如下:

展开Web层的Properties文件夹,双击打开里面的launchSettings.json文件,并在profiles节点里,完整代码如下:

"profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger/index.html",   //加上这句
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }

原文地址:https://www.cnblogs.com/yjj0720/p/aluo0720.html