ABP框架入门学习(二)——实体层/领域层/应用层实现
上篇文章写到下载模板,模板的结构简单介绍、生成数据库和基础数据,然后并运行了项目,接下来咋们说说项目的扩展,新建一块自己的业务,参照现有的项目架构,我们该怎么一步步增加自己的功能?
一、创建Book实体
前面有说道项目领域层是有两块组成:
在TestApp.BookStore.Domain创建一个Books的文件夹,并添加一个Book的基础类,如下图:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Volo.Abp.Domain.Entities.Auditing; namespace TestApp.BookStore.Books { public class Book :AuditedAggregateRoot<Guid> { public string Name { get; set; } public BookType Type { get; set; } public DateTime PublishDate { get; set; } public float Price { get; set; } } }
- ABP为实体提供了两个基本的基类:
AggregateRoot
和Entity
. Aggregate Root是领域驱动设计 概念之一. 可以视为直接查询和处理的根实体. Book
实体继承了AuditedAggregateRoot
,AuditedAggregateRoot
类在AggregateRoot
类的基础上添加了一些基础审计属性(例如CreationTime
,CreatorId
,LastModificationTime
等). ABP框架自动为你管理这些属性.Guid
是Book
实体的主键类型.
由于Book实体包含
枚举,所以在BookType
TestApp.BookStore.Domain.Shared
创建一个Books的文件夹,并添加一个BookType的基础类,如下图:

using System; using System.Collections.Generic; using System.Text; namespace TestApp.BookStore.Books { public enum BookType { Undefined, Adventure, Biography, Dystopia, Fantastic, Horror, Science, ScienceFiction, Poetry } }
二、将Book实体添加到DbContext中并映射到数据库表中
EF Core需要你将实体和 DbContext
建立关联.做法是在TestApp.BookStore.EntityFrameworkCore
项目的BookStoreDbContext
类
添加DbSet
属性.如下所示:
public DbSet<Book> Books { get; set; }
OnModelCreating
方法,为Book
实体添加映射代码:
builder.Entity<Book>(b => { b.ToTable(BookStoreConsts.DbTablePrefix + "Books",BookStoreConsts.DbSchema); b.ConfigureByConvention(); b.Property(x => x.Name).IsRequired().HasMaxLength(128); });
BookStoreConsts
含有用于表的架构和表前缀的常量值. 使用它不是强制的,但建议在统一的地方控制表前缀.ConfigureByConvention()
方法优雅的配置/映射继承的属性,应对所有的实体使用它.
可在数据模型添加初始化数据方便学习ABP Framework功能,如下图(可忽略)
在 TestApp.BookStore.Domain项目下创建 IDataSeedContributor
的派生类

using System; using System.Threading.Tasks; using TestApp.BookStore.Books; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; namespace TestApp.BookStore { public class BookStoreDataSeederContributor : IDataSeedContributor, ITransientDependency { private readonly IRepository<Book, Guid> _bookRepository; public BookStoreDataSeederContributor(IRepository<Book, Guid> bookRepository) { _bookRepository = bookRepository; } public async Task SeedAsync(DataSeedContext context) { if (await _bookRepository.GetCountAsync() <= 0) { await _bookRepository.InsertAsync( new Book { Name = "1984", Type = BookType.Dystopia, PublishDate = new DateTime(1949, 6, 8), Price = 19.84f }, autoSave: true ); await _bookRepository.InsertAsync( new Book { Name = "The Hitchhiker's Guide to the Galaxy", Type = BookType.ScienceFiction, PublishDate = new DateTime(1995, 9, 27), Price = 42.0f }, autoSave: true ); } } } }
- 如果数据库中当前没有图书,则此代码使用
IRepository<Book, Guid>
(默认repository)将两本书插入数据库.
三、更新数据库
由于数据表结构和初始化数据调整,所以需要更新下数据库,将TestApp.BookStore.DbMigrator应用程序设为启动项目,
来更新数据库,运行完成会发现数据库book表会多两条默认数据,如下图:
.DbMigrator
是一个控制台使用程序,可以在开发和生产环境迁移数据库架构和初始化种子数据.
四、创建应用程序
前面也说道应用程序跟领域层类似都有两块组成:
创建一个应用程序服务,使用ABP Framework的 CrudAppService
基类来获取,创建,更新和删除书籍.
CrudAppService
基类需要定义实体的基本DTO.
在 TestApp.BookStore.Application.Contracts
项目中创建 Books
文件夹(命名空间),添加 BookDto
的DTO类:
using System; using System.Collections.Generic; using System.Text; using Volo.Abp.Application.Dtos; namespace TestApp.BookStore.Books { public class BookDto:AuditedEntityDto<Guid> { public string Name { get; set; } public BookType Type { get; set; } public DateTime PublishDate { get; set; } public float Price { get; set; } } }
六、运行Swagger UI测试API
可以尝试执行[GET] /api/app/book
API来获取书籍列表, 服务端会返回以下JSON结果:
到现在为止新增的Book模块基本完成,下片接着介绍如何操作Book的增删改查功能......
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)