項目基于前兩篇文章.
本章建立一個簡單版的商品管理背景api,用到EF Core用code fist遷移資料建立資料庫.
建立Goods實體
在領域層xxx.Core項目[建立檔案夾Goods;檔案夾名稱和類名稱一樣後面引用的時候需要Goods.Goods,是以建議檔案夾名稱最好是不要與類同名]在檔案夾下建立Goods.cs實體類

[Table("goods")]
public class Goods : AuditedAggregateRoot<Guid>
{
/// <summary>
/// 商品名稱
/// </summary>
[Required]//必填
[StringLength(100)]//限制長度100
public string GoodsName { get; set; }
/// <summary>
/// 價格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Describe{ get; set; }
/// <summary>
/// 剩餘數量
/// </summary>
public int SurplusQty { get; set; }
/// <summary>
/// 構造函數
/// </summary>
/// <param name="goodsName"></param>
/// <param name="price"></param>
/// <param name="describe"></param>
/// <param name="surplusQty"></param>
public Goods(string goodsName, decimal price, string describe,int surplusQty)
{
GoodsName = goodsName;
Price = price;
Describe = describe;
SurplusQty = surplusQty;
}
}
ABP有兩個基本的實體基類:
AggregateRoot(領域驅動設計(DDD)的概念之一)
和
Entity,繼承AggregateRoot會預設添加審計屬性CreationTime,CreatorId
<Guid>
是
Goods
實體的主鍵類型可以是int,string等根據自己場景設定
将Goods實體添加到DbContext中
在基礎層xxx.EntityFrameworkCore下找到xxxDbContext.cs加入Goods實體對應的DbSet
//由于檔案夾名稱和類檔案同名是以需要Goods.Goods不然隻需要類名Goods就行了
public DbSet<Goods.Goods> Goods { get; set; }
添加新的Migration并更新資料庫
1,打開程式包管理器控制台,預設項目選擇Entityframework對應的項目後。執行
Add-Migration Add_Goods_Entity
,建立遷移
2,在程式包管理器控制台,輸入
Update-Database
,回車執行遷移。執行成功後,檢視資料庫,看是否存在表及初始資料
執行成功之後重新整理資料庫檢視是否有成功建立表goods
3,給goods表添加幾條初始化資料
3.1 在基礎層xxx.EntityFrameworkCore下建立Goods初始化資料類DefaultGoodsCreator.cs
public class DefaultGoodsCreator
{
private readonly crazyDbContext _context;
private List<crazy.Goods.Goods> GoodsList= GetInitialGoods();
public DefaultGoodsCreator(crazyDbContext context)
{
_context = context;
}
private static List<crazy.Goods.Goods> GetInitialGoods()
{
return new List<crazy.Goods.Goods>
{
new crazy.Goods.Goods("商品1",100,"描述1",10),
new crazy.Goods.Goods("商品2",260,"描述2",50),
new crazy.Goods.Goods("商品3",99,"描述2",1),
};
}
public void Create()
{
CreateGoods();
}
/// <summary>
/// 循環添加初始資料
/// </summary>
private void CreateGoods()
{
foreach (var goods in GoodsList)
{
AddGoodsIfNotExists(goods);
}
}
/// <summary>
/// 判斷添加不存在的商品資料
/// </summary>
/// <param name="goods"></param>
private void AddGoodsIfNotExists(crazy.Goods.Goods goods)
{
if (_context.Goods.IgnoreQueryFilters().Any(l => l.GoodsName == goods.GoodsName))
{
return;
}
_context.Goods.Add(goods);
_context.SaveChanges();
}
}
3.2在基礎層xxx.EntityFrameworkCore找到檔案夾Seed下的SeedHelper.cs插入代碼
//Goods初始化資料
new DefaultGoodsCreator(context).Create();
設定crazy.Web.Host為啟動項運作項目,運作之後資料庫就會生成goods初始化資料.
建立應用服務
1在應用服務層xxx.Application建立檔案夾Goods>Dto
①添加GoodsDto.cs注意:以下截圖中用的是AutoMapFrom(目前實體隻能轉為映射實體,目前實體必須字段跟映射實體一樣)這個是錯誤的正确的應該是下面代碼中的AutoMapTo(目前實體和映射實體可互相轉換,隻取必要字段不用全部比對)
[AutoMapTo(typeof(Goods))]
public class GoodsDto : AuditedEntityDto<Guid>
{
/// <summary>
/// 商品名稱
/// </summary>
public string GoodsName { get; set; }
/// <summary>
/// 價格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Describe { get; set; }
/// <summary>
/// 剩餘數量
/// </summary>
public int SurplusQty { get; set; }
}
[AutoMapTo(typeof(Goods))]
用來建立從
Goods
類到
GoodsDto
的AutoMapper映射.使用這種方法.你可以将
Goods
對象自動轉換成
GoodsDto
對象
②添加
CreateGoodsDto.cs用于在新增接口
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Runtime.Validation;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace crazy.Goods.Dto
{
[AutoMapTo(typeof(Goods))]
public class CreateGoodsDto : IShouldNormalize
{
/// <summary>
/// 商品名稱
/// </summary>
[Required]
[StringLength(100)]
public string GoodsName { get; set; }
/// <summary>
/// 價格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Describe { get; set; }
/// <summary>
/// 剩餘數量
/// </summary>
public int SurplusQty { get; set; }
/// <summary>
/// 初始化預設值
/// </summary>
public void Normalize()
{
SurplusQty = 999;
Price = 0.01M;
}
}
}
③建立商品查詢分頁類PagedGoodsResultRequestDto.cs
public class PagedGoodsResultRequestDto: PagedResultRequestDto
{
public string Keyword { get; set; }
}
④在應用服務層的Goods檔案夾下建立接口
IGoodsAppService.cs
public interface IGoodsAppService :
IAsyncCrudAppService< //定義了基礎的 CRUD方法:GetAsync, GetListAsync, CreateAsync, UpdateAsync 和 DeleteAsync.如果不需要擴充它,你可以繼承空的IApplicationService接口定義你自己的方法
GoodsDto, //展示商品
Guid, //Goods實體的主鍵
PagedGoodsResultRequestDto, //擷取商品的時候用于分頁和排序
CreateGoodsDto, //建立
GoodsDto> //更新
{
}
⑤在應用服務層的Goods檔案夾下建立商品服務類
GoodsAppService.cs
public class GoodsAppService :
AsyncCrudAppService<Goods, GoodsDto, Guid, PagedGoodsResultRequestDto,
CreateGoodsDto, GoodsDto>,
IGoodsAppService
{
public GoodsAppService(IRepository<Goods, Guid> repository)//注入IRepository自動為Goods建立倉儲
: base(repository)
{
}
/// <summary>
/// 查詢接口(使用Keyword查詢商品名稱)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
protected override IQueryable<Goods> CreateFilteredQuery(PagedGoodsResultRequestDto input)
{
return Repository.GetAll().WhereIf(!input.Keyword.IsNullOrWhiteSpace(), a => a.GoodsName.Contains(input.Keyword));
}
}
到此就可以運作項目得到如下效果
有夢想一定要去做
但是未必一定要實作