在上一章中,我們介紹了如何注入和使用,這都是我們平常用的最多技術點。
這一章呢,我們接着來講講,數據庫連接。這也是最實用的。 先不管啥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