• ABP领域层创建实体


    原文作者:圣杰

    原文地址:ABP入门系列(2)——领域层创建实体

    在原文作者上进行改正,适配ABP新版本。内容相同

    这一节我们主要和领域层打交道。首先我们要对ABP的体系结构以及从模板创建的解决方案进行一一对应。网上有代码生成器去简化我们这一步的任务,但是不建议初学者去使用。

    一、首先来看看ABP体系结构

    领域层就是业务层,是一个项目的核心,所有业务规则都应该在领域层实现。
    实体(Entity): 实体代表业务领域的数据和操作,在实践中,通过用来映射成数据库表。
    仓储(Repository): 仓储用来操作数据库进行数据存取。仓储接口在领域层定义,而仓储的实现类应该写在基础设施层。
    领域服务(Domain service): 当处理的业务规则跨越两个(及以上)实体时,应该写在领域服务方法里面。
    领域事件(Domain Event): 在领域层有些特定情况发生时可以触发领域事件,并且在相应地方捕获并处理它们。
    工作单元(Unit of Work): 工作单元是一种设计模式,用于维护一个由已经被修改(如增加、删除和更新等)的业务对象组成的列表。它负责协调这些业务对象的持久化工作及并发问题。

    二、再来看看解决方案

    确定了解决方案下每个项目分别对应那一层后,我们开始创建Task实体。

    三、创建Task实体

    1.在领域层创建Tasks文件夹,并创建Task实体类;
    2.ABP中所有的实体类都继承自Entity,而Entity实现了IEntity接口;而IEntity接口是一个泛型接口,通过泛型指定主键Id类型,默认的Entity的主键类型是int类型。
    创建Task,肯定需要保存创建时间,可以通过实现审计模块中的IHasCreationTime来实现这种通用功能。代码如下:

     1 using Abp.Domain.Entities;
     2 using Abp.Domain.Entities.Auditing;
     3 using Abp.Timing;
     4 using Coreqi.Authorization.Users;
     5 using System;
     6 using System.Collections.Generic;
     7 using System.ComponentModel.DataAnnotations;
     8 using System.ComponentModel.DataAnnotations.Schema;
     9 using System.Text;
    10 
    11 namespace Coreqi.Tasks
    12 {
    13     public class Task : Entity, IHasCreationTime
    14     {
    15         public const int MaxTitleLength = 256;
    16         public const int MaxDescriptionLength = 64 * 1024;
    17         public long? AssignedPersonId { get; set; }
    18         [ForeignKey("AssignedPersonId")]
    19         public User AssignedPerson { get; set; }
    20 
    21         [Required]
    22         [MaxLength(MaxTitleLength)]
    23         public string Title { get; set; }
    24 
    25         [Required]
    26         [MaxLength(MaxDescriptionLength)]
    27         public string Description { get; set; }
    28 
    29         public TaskState State { get; set; }
    30 
    31         public DateTime CreationTime { get; set; }
    32 
    33         public Task()
    34         {
    35             CreationTime = Clock.Now;
    36             State = TaskState.Open;
    37         }
    38         public Task(string title ,string description = null): this()
    39         {
    40             Title = title;
    41             Description = description;
    42         }
    43     }
    44     public enum TaskState : byte
    45     {
    46         Open = 0,
    47         Completed = 1
    48     }
    49 }

    其中定义了TaskState状态枚举。并添加了AssignedPerson导航属性,用来保存分配任务到某个用户。其中[Required]、[MaxLength]特性是用来进行输入校验的。

    3.定义好实体之后,我们就要去DbContext中定义实体对应的DbSet,以应用Code First 数据迁移。找到我们的基础服务层,即以EntityFramework结尾的项目中,找到DbContext类,添加以下代码

     1 using Microsoft.EntityFrameworkCore;
     2 using Abp.Zero.EntityFrameworkCore;
     3 using Coreqi.Authorization.Roles;
     4 using Coreqi.Authorization.Users;
     5 using Coreqi.MultiTenancy;
     6 using Coreqi.Tasks;
     7 
     8 namespace Coreqi.EntityFrameworkCore
     9 {
    10     public class CoreqiDbContext : AbpZeroDbContext<Tenant, Role, User, CoreqiDbContext>
    11     {
    12         /* Define a DbSet for each entity of the application */
    13         public DbSet<Task> Tasks { get; set; }
    14         public CoreqiDbContext(DbContextOptions<CoreqiDbContext> options)
    15             : base(options)
    16         {
    17         }
    18     }
    19 }

    4.执行Code First数据迁移。

    • 打开程序包管理器控制台,默认项目选择Entityframework对应的项目后。执行Add-Migration Add_Task_Entity,创建迁移。
    • 创建成功后,会在Migrations文件夹下创建时间_Add_Task_Entity格式的类文件。
    • 在EntityFrameworkCore=》Seed=》Host目录下新建DefaultTaskCreator类用于预置两条Task种子数据。
     1 using Coreqi.Tasks;
     2 using System;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 
     7 namespace Coreqi.EntityFrameworkCore.Seed.Host
     8 {
     9     public class DefaultTaskCreator
    10     {
    11         private readonly CoreqiDbContext _context;
    12 
    13         private static readonly List<Task> _tasks;
    14 
    15         public DefaultTaskCreator(CoreqiDbContext context)
    16         {
    17             _context = context;
    18         }
    19 
    20         static DefaultTaskCreator()
    21         {
    22             _tasks = new List<Task>()
    23             {
    24                 new Task("Learning ABP deom", "Learning how to use abp framework to build a MPA application."),
    25                 new Task("Make Lunch", "Cook 2 dishs")
    26             };
    27         }
    28 
    29         public void Create()
    30         {
    31             CreateTasks();
    32         }
    33 
    34         private void CreateTasks()
    35         {
    36             foreach (var task in _tasks)
    37             {
    38                 if (_context.Tasks.FirstOrDefault(t => t.Title == task.Title) == null)
    39                 {
    40                     _context.Tasks.Add(task);
    41                 }
    42                 _context.SaveChanges();
    43             }
    44         }
    45     }
    46 }

    然后在InitialHostDbBuilder类中的Create方法中,添加以下代码。

     1         public void Create()
     2         {
     3             new DefaultEditionCreator(_context).Create();
     4             new DefaultLanguagesCreator(_context).Create();
     5             new HostRoleAndUserCreator(_context).Create();
     6             new DefaultSettingsCreator(_context).Create();
     7 
     8             //add
     9             new DefaultTaskCreator(_context).Create();
    10 
    11             _context.SaveChanges();
    12         }

    在程序包管理器控制台,输入Update-Database,回车执行迁移。执行成功后,运行xxxx.Web.Host项目,查看数据库,Tasks表创建成功,且表中已存在两条测试数据。

      至此,Task实体类成功创建。

  • 相关阅读:
    数据库的数据同步
    IDEA连接数据库自动生成实体类
    异常日记(一)
    高16位,低16位是什么
    springboot整合rabbitmq
    springBoot使用教程
    分布式框架Dubbo入门
    Spring注解驱动开发04(给容器中注册组件的方式)
    Spring注解驱动开发03(按照条件注册bean)
    Spring注解驱动开发02(作用域和懒加载)
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/11042138.html
Copyright © 2020-2023  润新知