利用DI實現級聯刪除 – xms跨平台基礎框架 – 基於.netcore
- 2019 年 11 月 13 日
- 筆記
一、引言
所謂級聯刪除是指刪除一條記錄後,附帶關聯記錄也一起刪除,比如刪除客戶後,聯繫人也一起刪除;
以往我們會依賴於資料庫表的外鍵約束,但存在著明顯的問題,增加資料庫壓力、提示不友好、職責越界、事務衝突等,這類業務相關的功能不應該放到資料庫去管理。
二、依賴注入
DI、IOC等概念在這不展開介紹,大家記住它們的主要目的就是解耦,本文利用.netcore內置的DI實現相關功能
二、解決方案
利用DI注入級聯刪除的服務,在主體刪除時獲取已註冊的級聯刪除服務,實現記錄的級聯刪除,前面這句話可能繞口,下面用一個例子說明,刪除【實體元數據】時同時刪除【欄位元數據】,看下程式碼就清晰了:
級聯刪除介面類 ICascadeDelete
1 public interface ICascadeDelete<TParent> 2 { 3 void CascadeDelete(params TParent[] parent); 4 }
欄位刪除類 AttributeDeleter,實現上面的介面
1 public class AttributeDeleter : ICascadeDelete<Domain.Entity> 2 { 3 private readonly IAttributeRepository _attributeRepository; 4 public AttributeDeleter(IAttributeRepository attributeRepository) 5 { 6 _attributeRepository = attributeRepository; 7 } 8 9 /// <summary> 10 /// 實體級聯刪除 11 /// </summary> 12 /// <param name="parent">被刪除的實體</param> 13 public void CascadeDelete(params Domain.Entity[] parent) 14 { 15 //刪除欄位 16 _attributeRepository.DeleteMany(x =>x.EntityId.In(parent.Select(x => x.EntityId).ToArray())); 17 } 18 }
實體刪除類EntityDeleter
1 public class EntityDeleter 2 { 3 private readonly IEntityRepository _entityRepository; 4 private readonly IEnumerable<ICascadeDelete<Domain.Entity>> _cascadeDeletes;//需要同時刪除記錄的服務類 5 public EntityDeleter(IEntityRepository entityRepository 6 , IEnumerable<ICascadeDelete<Domain.Entity>> cascadeDeletes 7 ) 8 { 9 _entityRepository = entityRepository; 10 _cascadeDeletes = cascadeDeletes; 11 } 12 13 14 public bool DeleteById(Guid id) 15 { 16 //執行級聯刪除,一般放在主記錄刪除前 17 _cascadeDeletes?.ToList().ForEach((x) => { x.CascadeDelete(deleted); }); 18 //刪除實體 19 _entityRepository.DeleteById(id); 20 } 21 }
註冊服務
services.AddScoped(typeof(Core.Data.ICascadeDelete<>), typeof(Core.Data.ICascadeDelete<Domain.Entity>));
上面的服務註冊方式是固定的寫法,但實際項目可能有很多這類同一介面的實現,我們可以寫個批量註冊的類去解決,後面再介紹,大家也可以自己查看源碼
三、結語
整個過程很簡單,但解決了系統設計的幾個大問題,包括大家從我的類命名(EntityDeleter)就可以看出,這是職責單一的設計思想,xms應用了很多設計模式,日後會在這裡一一分享,這些模式帶來的巨大好處