ABP-VNEXT 学习笔记(二)数据库连接

在上一章中,我们介绍了如何注入和使用,这都是我们平常用的最多技术点。

这一章呢,我们接着来讲讲,数据库连接。这也是最实用的。  先不管啥DDD的,ABP只是个基础框架,想怎么用都行。

示例环境:

数据库:mysql

ORM:EFCORE

这里的数据库表结构我是手动创建的,没有用dbfirst模式进行迁移。

开始

首先我们新建一个类库,叫TestModel,然后创建一个实体Users

using System.ComponentModel.DataAnnotations.Schema;
using Volo.Abp.Domain.Entities;

namespace TestModel
{
    [Table("Users")]
    public class Users: Entity<string>
    {
        public string Name { get; set; }


    }
}

类库需要引用下面的包:

 

 

 这个包里提供聚合根Entity<string>。


在ABP中,一般我们实体都会继承一个聚合根,比如ABP中规范的Entity<string>,这个实体包含一个 固定字段,Id,string为指定的类型,也可以指定为Guid。

数据库中的字段如下图:

 

 

 简单示例,就2个字段。

 

然后,按照常规3层 ,我们建一个服务层类库TestService,专门处理业务逻辑的,当然要引用实体层,实现对实体操作。

因为我们是使用EF框架的,所以需要引入ABP的EFcore包。在这里需要明白的是,我们服务层是只引入了EFCORE,而EFCORE本身是支持sqlserver,mysql等多种数据库的。也就是说我们服务层也是支持的。至于具体使用什么数据,在web层去选择。

 

 

 

我们把数据层上下文对象也放到这里来定义,定义一个MyDbContext 上下文对象

using Microsoft.EntityFrameworkCore;
using TestModel;
using Volo.Abp.EntityFrameworkCore;

namespace TestService
{
    //[ConnectionStringName("Default")] //这里可以自定义连接的字符串,对应appsetting.json中ConnectionStrings的子节点,不指定会默认查找Default节点的配置
    public class MyDbContext : AbpDbContext<MyDbContext>
    {
        public DbSet<Users> users { get; set; }

        public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
        }
    }
}

 

然后创建 IUserService  接口

namespace TestService
{
    public  interface IUserService
    {
        string GetName(string id);
    }
}

再创建一个实现:

using System.Linq;
using System.Linq.Dynamic.Core;
using TestModel;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;

namespace TestService
{
    public class UserService : IUserService, IScopedDependency
    {
        private readonly MyDbContext _dbContext;
        private readonly IRepository<Users, string> _users;
        public UserService(MyDbContext dbContext, IRepository<Users, string> users)
        {
            _dbContext = dbContext;
            _users = users;
        }
        public string GetName(string id)
        {
            // return _dbContext.users.FirstOrDefault(m => m.Id == id)?.Name;
            return _users.FirstOrDefault(m => m.Id == id)?.Name;
        }
    }
}

在这个实现里面,我们有2种方式获取数据

1:通过注册的数据库上下文来实现

2:通过abp默认的仓储来实现。

当然,以上都需要对应注册了,才能使用。接下来我们还要创建一个继承AbpModule 模块的类。

每个需要注入的类库都需要一个,用于依赖到启动模块,实现该类库的注入。代码如下:

using Volo.Abp.Modularity;

namespace TestService
{
    public class TestServiceModule: AbpModule
    {
      
    }
}

所有的注入工作,都在AbpModule模块中实现。所以类库需要增加这个继承,再根据每个类自己依赖的IScopedDependency等类型进行注入。

OK,至此,我们服务层的工作已经完成了。

 

接下来,Web层。

创建一个MVC的应用,引用如下模块包

 

 

 

其中, 

Volo.Abp.AspNetCore.Mvc:模块是MVC项目需要

Volo.Abp.Core:是ABP的核心库

Volo.Abp.EntityFrameworkCore.MySQL:这个是我们需要连接的数据库类型。 如果是sqlserver,那就选择安装Volo.Abp.EntityFrameworkCore.SqlServer

同时,还要引入实体层和服务层两个项目。

接下来,跟上一章节类似,我们创建一个AppModule的启动类:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TestService;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;

namespace WebApplication1.Models
{
    [DependsOn(
        typeof(AbpAspNetCoreMvcModule), //启动MVC模块
        typeof(AbpEntityFrameworkCoreModule), //启动EFCODE模块
        typeof(TestServiceModule) //启动服务层模块
        )] 
    public class AppModule:AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAbpDbContext<MyDbContext>(options => { //注入上下文对象
            options.AddDefaultRepositories(includeAllEntities: true);//自动为DbContext中的实体创建默认仓储,默认是为继承了Entity<Guid>的实体创建仓储,如果其他实体也要创建,必须设置includeAllEntities: true
          

            }); //配置注入
            Configure<AbpDbContextOptions>(options => {
                options.UseMySQL(); //选择使用mysql数据库
            });



        }

        
        /// <summary>
        /// 在启动模块初始化中,我们就可以把startup中的配置都搬过来
        /// </summary>
        /// <param name="context"></param>
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }


            app.UseRouting();


            app.UseConfiguredEndpoints();
        }
    }
}

这个启动模块类,我们需要依赖3个
1、mvc是必须的,由abp框架提供

2、AbpEntityFrameworkCoreModule是使用EF必须的,由abp框架提供

3、TestServiceModule 这个是实现我们服务层的注入,由我们自己定义。

然后通过下面代码实现上下文注入

 context.Services.AddAbpDbContext<MyDbContext>(options => { //注入上下文对象
            options.AddDefaultRepositories(includeAllEntities: true);//自动为DbContext中的实体创建默认仓储,默认是为继承了Entity<Guid>的实体创建仓储,如果其他实体也要创建,必须设置includeAllEntities: true
          

            }); //配置注入

 

然后配置我们的数据库类型:

  Configure<AbpDbContextOptions>(options => {
                options.UseMySQL(); //选择使用mysql数据库
            });

如果是其他类型,那需要引用对应的包,这边才能使用对应的数据库。

完成启动类注入后,appsetting.json 进行配置我们的连接字符串,

使用默认配置的话,ConnectionStrings名称不能变。
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Default": "server=192.168.20.134;port=3306;database=eftest;uid=root;pwd=3BIW#lP211HkB4Yq;CharSet=utf8;"
    //"AbpIdentityServer": "Server=localhost;Database=MyIdsDb;Trusted_Connection=True;",
    //"AbpPermissionManagement": "Server=localhost;Database=MyPermissionDb;Trusted_Connection=True;"
  }
}

然后,startup中一样实现启动模块

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<AppModule>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.InitializeApplication();
        }

 

OK,至此就完成了整个项目的配置。接下来测试,

在home控制中调用服务层输出。

    public class HomeController : AbpController //控制器必须继承 AbpController
    {

        private readonly IUserService _userService;
        public HomeController(IUserService userService)  {
            _userService = userService;
        }

        public IActionResult Index()
        {
            return Content(_userService.GetName("c52c1c0e110146c2b785ab2800fff2f0"));
        }

    }

输出结果:

 

 

数据库数据:

 

 

正确,完成数据库的操作示例。

代码:示例代码地址:https://gitee.com/fei686868/abpvnext-learning-shili

 

更多分享,请大家关注我的个人公众号:

 

posted @ 2021-03-29 15:18  黄明辉  阅读(1937)  评论(1编辑  收藏  举报