Abp系列 一. "abp框架運行——前後端分離(基於VUE)" 二. "基於abp框架的資料庫種子數據初始化" 基於abp框架的資料庫種子數據初始化 [toc] 1.背景 最近在用abp開發項目,需要將如下區域數據通過程式的初次運行種入資料庫。 不知道大家是怎麼去管理資料庫跟後臺程式的同步的, " ...
目錄
- Abp系列
- 一.abp框架運行——前後端分離(基於VUE)
- 二.基於abp框架的資料庫種子數據初始化
- 基於abp框架的資料庫種子數據初始化
- 1.背景
- 2.參照
- 3.解決方案
- 4.效果
- 5. Area實體
- 6.小結
Abp系列
一.abp框架運行——前後端分離(基於VUE)
二.基於abp框架的資料庫種子數據初始化
基於abp框架的資料庫種子數據初始化
1.背景
最近在用abp開發項目,需要將如下區域數據通過程式的初次運行種入資料庫。
不知道大家是怎麼去管理資料庫跟後臺程式的同步的,基於Git的資料庫sql文件的管理——完美解決團隊sql操作協同問題,此文是我以前的一個思考。
但是有三個缺點:
- 運維總會忘記去更新資料庫,導致異常;
- 不同的後端有時候也難以同步;
- 管理sql本身要耗費一定的經歷。
綜上,此次開發決定資料庫的初始化數據寫在程式中,與程式一同管理。解決了上述三個問題。
備註本文用的abp框架為第一代,官網:https://aspnetboilerplate.com/。 模板下載運行方法(前後端分離)可以參照此文abp框架運行——前後端分離(基於VUE)。
2.參照
本文執行方法參照的是abp框架的預設語言種子數據種入。
3.解決方案
3.1 初始化數據
//初始化區域數據的引用
public List<Area> InitialArea => GetInitialArea();
/// <summary>
/// 初始化數據
/// </summary>
/// <returns></returns>
private List<Area> GetInitialArea()
{
return new List<Area>
{
new Area(110000,"北京市", 0, 1),
new Area(110101,"東城區", 110100, 3),
new Area(110102,"西城區", 110100, 3)
};
}
3.2 依賴註入方法容器里獲取資料庫上下文
構造函數,通過依賴註入容器拿到資料庫上下文。
//PEMS系統資料庫上下文
private readonly PEMSDbContext _context;
/// <summary>
/// 構造函數,通過依賴註入容器拿到資料庫上下文
/// </summary>
/// <param name="context"></param>
public DefaultAreaCreator(PEMSDbContext context)
{
_context = context;
}
對依賴註入不明白的道友,可以參照此文 在net Core3.1上基於winform實現依賴註入實例
3.3 封裝創建初始化數據列表方法
/// <summary>
/// 封裝調用 創建初始化數據列表方法,這樣上層調用看上去格式一致
/// </summary>
public void Create()
{
CreateArea();
}
/// <summary>
/// 創建初始化數據列表方法
/// </summary>
private void CreateArea()
{
foreach (var area in InitialArea)
{
AddAreaIfNotExists(area);
}
}
遍歷初始區域表,將數據加入到資料庫中去。
3.4 資料庫中沒有的初始化數據,補充到資料庫中去
通過資料庫上下文,獲取資料庫中的區域id區功能變數名稱稱。與初始化數據對比,丟失的數據,添加到資料庫里去。
/// <summary>
/// 某個區域記錄缺失時,將該記錄重新種入資料庫進行持久化
/// </summary>
/// <param name="area"></param>
private void AddAreaIfNotExists(Area area)
{
if (_context.Area.IgnoreQueryFilters().Any(a => a.Id== area.Id && a.AreaName == a.AreaName))
{
return;
}
_context.Area.Add(area);
_context.SaveChanges();
}
4.效果
資料庫中沒有數據或者缺失某條或者某幾條記錄。結果都是如下初始數據。
5. Area實體
位於項目的領域層。
/// <summary>
/// Area實體類
/// </summary>
public class Area : Entity<long>
{
public Area()
{
}
public Area(int id, string areaName, int parentID, int level)
{
this.Id = id;
this.AreaName = areaName;
this.ParentID = parentID;
this.level = level;
}
[StringLength(20)]
public string AreaName { get; set; }
public int ParentID { get; set; }
public int level { get; set; }
}
- Entity
是Abp.Domain.Entities命名空間中的一個基類,可以指定Id的類型。 - 需要如下構造函數為了方便初始化數據調用
public Area(int id, string areaName, int parentID, int level)
{
this.Id = id;
this.AreaName = areaName;
this.ParentID = parentID;
this.level = level;
}
- 另外還需要個空構造函數,為了EFCore能夠正常使用。
public Area()
{
}
6.小結
- 本文提供了一種管理後臺程式和資料庫表結構和初始化數據的一種方案(基於EFCore)。不適合Dapper等半自動無法CodeFirst的ORM。
- ABP框架的種子數據種入資料庫,會獲取到資料庫上下文,掃描出表中缺失的數據,補錄丟失的某條或者某幾條記錄。