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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM