ABP学习 之 实现数据操作

数据操作

之前已经学习添加了新API,以及对该API如何进行权限拦截。大多数情况下,我们的API都是要实现数据操作的。那么如何进行数据操作?
要进行数据操作的话,首先要添加实体类,DTO类,配置Dbset, 数据库等一系列工作。

添加实体类,DTO类

实体类,我的理解是这个类的数据是与数据库交流的; DTO类,我的理解是这个类的数据是前后端进行数据交流的。

实体类

实体类在xxx.Core Project添加。我在该Project下建了一个Domain目录,在该目录下添加了一个继承Entity的FileStamp类。代码如下:

using Abp.Domain.Entities;

namespace MyLearningProject.Domain
{
    public class FileStamp : Entity<int>
    {
        public string FileName
        { get; set; }
        public string ExtName
        { get; set; }
        public string FilePath
        { get; set; }
        public int Size
        { get; set; }
        public string MD5
        { get; set; }
        public string SHA512
        { get; set; }
    }
}

DTO类

DTO类在xxxx.Application Project添加。我在该Project下新建一个FileStamp/Dto两层目录,在Dto目录下添加一个继承EntityDto的FileStampDto类。代码如下:

using Abp.Application.Services.Dto;
using Abp.AutoMapper;

namespace MyLearningProject.FileStamp.Dto
{
    [AutoMap(typeof(Domain.FileStamp))]
    public class FileStampDto:EntityDto<int>
    {
        public string FileName
        { get; set; }
        public string ExtName
        { get; set; }
        public string FilePath
        { get; set; }
        public int Size
        { get; set; }
        public string MD5
        { get; set; }
        public string SHA512
        { get; set; }
    }
}

重点是,该类需要添加AutoMap 特性,typeof要匹配这个Dto对应的实体类AutoMap(typeof(Domain.FileStamp))

添加DbSet 及 初始化代码

添加DbSet

DbSet在xxxx.EnityFrameworkCore Project添加。该Project下有个EntityFrameworkCore目录,内有xxxDbContext类,在该类内添加相应的DbSet就OK了。代码如下:

using Microsoft.EntityFrameworkCore;
using Abp.Zero.EntityFrameworkCore;
using MyLearningProject.Authorization.Roles;
using MyLearningProject.Authorization.Users;
using MyLearningProject.MultiTenancy;
using MyLearningProject.Domain;

namespace MyLearningProject.EntityFrameworkCore
{
    public class MyLearningProjectDbContext : AbpZeroDbContext<Tenant, Role, User, MyLearningProjectDbContext>
    {
        public MyLearningProjectDbContext(DbContextOptions<MyLearningProjectDbContext> options)
            : base(options)
        {
        }

        /* Define a DbSet for each entity of the application */
        public DbSet<FileStamp> FileStamp { set; get; }
    }
}

数据初始化代码

如果该类需要有初始数据的话,则需要在Seed目录下的SeedHelper内,在其静态方法SeedHostDb内添加相应的代码。例如:

public static void SeedHostDb(MyLearningProjectDbContext context)
{
    context.SuppressAutoSetTenantId = true;

    // Host seed
    new InitialHostDbBuilder(context).Create();

    // Default tenant seed (in host database).
    new DefaultTenantBuilder(context).Create();
    new TenantRoleAndUserBuilder(context, 1).Create();

	// 添加数据初始化代码
    new DefaultFileStampCreator(context).Create();
}

DefaultFileStampCreator类的代码:

using Microsoft.EntityFrameworkCore;
using MyLearningProject.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyLearningProject.EntityFrameworkCore.Seed.Domain
{
    public class DefaultFileStampCreator
    {
        private readonly MyLearningProjectDbContext _context;
        private List<FileStamp> FileInfoList = GetInitialFileInfos();
        public DefaultFileStampCreator(MyLearningProjectDbContext context)
        {
            _context = context;
        }

        private static List<FileStamp> GetInitialFileInfos()
        {
            return new List<FileStamp>
            {
                new FileStamp{FileName="test"},
            };
        }

        public void Create()
        {
            CreateFileInfos();
        }

        private void CreateFileInfos()
        {
            foreach (var info in FileInfoList)
            {
                AddFileInfoIfNotExists(info);
            }
        }

        private void AddFileInfoIfNotExists(FileStamp info)
        {
            if (_context.FileStamp.IgnoreQueryFilters().Any(l => l.FileName == info.FileName))
            {
                return;
            }
            _context.FileStamp.Add(info);
            _context.SaveChanges();
        }
    }
}

Data Migration

以上准备工作完成后,则需要进行数据库修改工作了
ABP提供了两个命令协助我们很方便的实现Data Migration

  1. 我们需要进入 程序包管理器控制台界面

  2. 选择EntityFrameworkCore项目

  3. 在PM>命令行执行add-migration "要生成的文件名"

    这时系统就会检查相关变更,自动生成#日期#_#要生成的文件名#.cs以及.Designer.cs两个文件
    
  4. 在PM>命令行执行Update-Database

    这时系统就会执行新生成的两个文件内的代码,更新数据库 
    

在这里插入图片描述

添加API

在xxxx.Application Project添加。刚才在添加Dto时,已经新建了一个FileStamp目录,在该目录下添加一个接口一个类:

using Abp.Application.Services;

namespace MyLearningProject.FileStamp
{
    public interface IFileStampAppService : IAsyncCrudAppService<Dto.FileStampDto, int>
    {
    }
}
using Abp.Domain.Repositories;

namespace MyLearningProject.FileStamp
{
    public class FileStampAppService : AsyncCrudAppService<Domain.FileStamp, Dto.FileStampDto, int>, IFileStampAppService
    {
        public FileStampAppService(IRepository<Domain.FileStamp, int> repository) : base(repository)
        { }
    }
}

这样就实现了对FileStamp的CRUD了。
在这里插入图片描述

实体类的修改

将FileStamp继承Entity<int>改为继承AuditedEntity<long>

using Abp.Domain.Entities.Auditing;

namespace MyLearningProject.Domain
{
    public class FileStamp : AuditedEntity<long>
    {
        public string FileName
        { get; set; }
        public string ExtName
        { get; set; }
        public string FilePath
        { get; set; }
        public int Size
        { get; set; }
        public string MD5
        { get; set; }
        public string SHA512
        { get; set; }
    }
}
  1. 进入 程序包管理器控制台界面
  2. 选择EntityFrameworkCore项目
  3. 在PM>命令行执行add-migration "update-FileStamp"
  4. 在PM>命令行执行Update-Database

这时会触发SqlException:
System.Data.SqlClient.SqlException (0x80131904): The object ‘PK_FileStamp’ is dependent on column ‘Id’.
在这里插入图片描述
因为刚自动生成的Migration要修改Id的类型,而Id已经作为PK存在,因此,要人手修改代码进行处理。
需要在Up Method一开始添加删除PK,最后完成修改后再添加PK。
而在Down Method结束时加上添加PK.
原自动生成的代码:

public partial class updateFileStamp : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterColumn<long>(
            name: "Id",
            table: "FileStamp",
            nullable: false,
            oldClrType: typeof(int))
            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
            .OldAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
           ......

修改为:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.DropPrimaryKey("PK_FileStamp", "FileStamp"); // 人手添加的

    migrationBuilder.AlterColumn<long>(
        name: "Id",
        table: "FileStamp",
        nullable: false,
        oldClrType: typeof(int))
        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
        .OldAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

    migrationBuilder.AddColumn<DateTime>(
        name: "CreationTime",
        table: "FileStamp",
        nullable: false,
        defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));

    migrationBuilder.AddColumn<long>(
        name: "CreatorUserId",
        table: "FileStamp",
        nullable: true);

    migrationBuilder.AddColumn<DateTime>(
        name: "LastModificationTime",
        table: "FileStamp",
        nullable: true);

    migrationBuilder.AddColumn<long>(
        name: "LastModifierUserId",
        table: "FileStamp",
        nullable: true);

    migrationBuilder.AddPrimaryKey("PK_FileStamp", "FileStamp", "Id"); // 人手添加的
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.DropColumn(
        name: "CreationTime",
        table: "FileStamp");

    migrationBuilder.DropColumn(
        name: "CreatorUserId",
        table: "FileStamp");

    migrationBuilder.DropColumn(
        name: "LastModificationTime",
        table: "FileStamp");

    migrationBuilder.DropColumn(
        name: "LastModifierUserId",
        table: "FileStamp");

    migrationBuilder.AlterColumn<int>(
        name: "Id",
        table: "FileStamp",
        nullable: false,
        oldClrType: typeof(long))
        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn)
        .OldAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

    migrationBuilder.AddPrimaryKey("PK_FileStamp", "FileStamp", "Id"); // 人手添加的
}

修改完成后,再次执行Update-Database, 成功执行。
运行程序,测试。一切OK。😘✌️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值