目录
一、前言
更详细介绍:官网的框架列表
二、上节回顾
上节我们写了实体、枚举、创建了数据表,添加了种子数据,最后还卸载了迁移项目
三、新建Dto和添加映射
1.新建dto
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.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; }
}
}
2.添加映射规则
CreateMap<Book, BookDto>().ReverseMap();//添加Model-Dto映射规则
四、新建WebApi控制器用EFcore进行增删改查
1.新建Webapi控制器接口
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Books
{
public interface IBookAppService : IApplicationService
{
Task<List<BookDto>> GetListAsync();
Task<bool> DeleteAsync(Guid id);
Task<bool> CreateAsync(BookDto input);
Task<bool> UpdateAsync(BookDto input);
}
}
2.新建Webapi控制器实现
若缺少mvc包,需要安装!
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Books
{
[Route("api/books")]
public class BookAppService : ApplicationService, IBookAppService
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookAppService(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
/// <summary>
/// 创建书本
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Route("createbook")]
[HttpPost]
public async Task<bool> CreateAsync(BookDto input)//可上拉接口,下同
{
var book = ObjectMapper.Map<BookDto, Book>(input);
await _bookRepository.InsertAsync(book);
return true; // 创建成功
}
/// <summary>
/// 获取书本
/// </summary>
/// <returns></returns>
[Route("getbook")]
[HttpGet]
public async Task<List<BookDto>> GetListAsync()
{
var books = await _bookRepository.GetListAsync();
return ObjectMapper.Map<List<Book>, List<BookDto>>(books);
}
/// <summary>
/// 更新书本
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Route("updatebook")]
[HttpPut]
public async Task<bool> UpdateAsync(BookDto input)
{
var book = await _bookRepository.GetAsync(input.Id);
ObjectMapper.Map(input, book);
await _bookRepository.UpdateAsync(book);
return true;
}
/// <summary>
/// 删除书本
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[Route("delbook")]
[HttpDelete]
public async Task<bool> DeleteAsync(Guid id)
{
var book = await _bookRepository.FirstOrDefaultAsync(x=>x.Id==id);
if (book != null)
{
await _bookRepository.DeleteAsync(id);
return true; // 删除成功
}
return false; // 找不到该书籍
}
}
}
【注意】这里的仓储,引用的是Volo.Abp.Domain.Repositories.IRepository。
3.跑项目测试
设置它为启动项目
开启redis,检查连接字符串是否正确,然后跑项目,出现swagger界面后可以调试接口:
五、WebApi控制器调用底层代码
1.webapi控制器(高层代码)
using Acme.BookStore.BooksService;
using Acme.BookStore.IBooksSevice;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
namespace Acme.BookStore.Books
{
[Route("api/books")]
public class BookAppService : ApplicationService, IBookAppService //高层代码一般继承ApplicationService
{
private readonly IBookService _bookService;
public BookAppService(BookService bookService)
{
_bookRepository = bookRepository;
_bookService = bookService;
}
/// <summary>
/// 通过底层代码获取书本
/// </summary>
/// <returns></returns>
[Route("getbookbybll")]
[HttpGet]
public async Task<List<BookDto>> GetListByBLLAsync()
{
var list = await _bookService.GetBooks();
return list;
}
}
}
2.底层代码接口
namespace Acme.BookStore.IBooksSevice
{
public interface IBookService
{
Task<List<BookDto>> GetBooks();
}
}
3.底层代码实现
这里的底层代码应该要进行更复杂的BLL(业务逻辑)处理,这里省略了复杂的逻辑,只查表返回!
using Acme.BookStore.Books;
using Acme.BookStore.IBooksSevice;
using AutoMapper.Internal.Mappers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Application.Services;
using static System.Reflection.Metadata.BlobBuilder;
using Volo.Abp.DependencyInjection;
namespace Acme.BookStore.BooksService
{
//底层代码一般继承ITransientDependency即可,当然继承ApplicationService也可以
public class BookService : ApplicationService, IBookService//必须继承ApplicationService,因为其继承了ITransientDependency,保证了服务被正确注入到依赖容器,高层代码才能调用这个底层代码,继承了它还可以调用ObjectMapper方法
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookService(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
public async Task<List<BookDto>> GetBooks() //上拉到接口
{
var entitylist = await _bookRepository.ToListAsync();
var dtolist = ObjectMapper.Map<List<Book>, List<BookDto>>(entitylist);
//省略更多的逻辑处理.....
return dtolist;
}
}
}
六、EFcore使用小结
1.EFcore的配置步骤
①配置实体类长度和类型(bulder.Entity)
②配置上下文类(连接字符串,dbset)
③Webapi控制器注入使用
2.步骤一:配置实体类长度和类型
【EFcore/DbContextModelCreatingExtensions】
【仓储层】配置实体类(例如表的实体类字段类型、长度,确保映射成功)
public static class DbContextModelCreatingExtensions
{
public static void ConfigureCommon(this ModelBuilder builder)//扩展方法
{
builder.Entity<Student>(b => { b.ConfigureByConvention(); });//ConfigureByConvention方法配置了字段,实现方法略
}
}
具体的写法可以参考:
builder.Entity<Student>(b =>
{
// 配置 Id 字段
b.HasKey(s => s.Id); // 设置 Id 为主键
// 配置 Age 字段
b.Property(s => s.Age)
.IsRequired() // 设置 Age 字段为必填
.HasColumnName("Age") // 设置数据库列名
.HasColumnType("int"); // 设置数据库列的类型
// 配置 Name 字段
b.Property(s => s.Name)
.IsRequired() // 设置 Name 字段为必填
.HasMaxLength(100) // 设置最大长度为 100
.HasColumnName("Name") // 设置数据库列名
.HasColumnType("nvarchar(100)"); // 设置数据库列的类型
// 配置 Time 字段
b.Property(s => s.Time)
.IsRequired() // 设置 Time 字段为必填
.HasColumnName("Time") // 设置数据库列名
.HasColumnType("datetime"); // 设置数据库列的类型
// 其他配置
// 可以设置表名、索引、关系等
b.ToTable("Students"); // 设置表名为 Students
});
3.步骤二:配置上下文类
【EFcore/DbContext】
【仓储层】上下文类(连接字符串配置,确保找到该表)
[ConnectionStringName(“连接字符串”)]
public DbSet<Student> Student { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureCommon();//关联DbContextModelCreatingExtensions.cs的方法
}
4.步骤三:Webapi控制器注入使用
【Application】
【应用层】Webapi控制器调用
public class AService:
{
private readonly IRepository<Student, int> _Students;//私有可访问字段
public DATForeignStationDataAppService(IRepository<Student, int> Students)
{
_Students = Students;//注入仓储接口
}
}
//接口写法:
//var list = _Students.Where(x=>x.id==1).ToList();//使用仓储