前言:
爲實現在ABP中實現級聯刪除。
以前參照過ABP工作單元實現過一套符合公司業務要求的工作單元。
1. 如何實現ABP EF Sqlite 級聯刪除?
參考鏈接地址 https://stackoverflow.com/questions/5890250/on-delete-cascade-in-sqlite3
sqlite 默認是沒有啓用外鍵的,需要每次連接數據庫時,執行 “PRAGMA foreign_keys = ON”命令。
而ABP中使用 倉儲服務“IRepository”時,DBContext 已經幫我們創建好了。
那麼現在的問題就是 如何在DBContext創建好之後,立即執行 “PRAGMA foreign_keys = ON”命令,這就從程序的角度上實現了Sqlite的級聯刪除。
2. ABP Vnext中DBContext由如何創建?
快速查找(我使用的是 Resharper ,F12 Resharper自動下載的相關源代碼)
查看源代碼
這裏使用的EF,選EFCore倉儲這實現
在這個 EfCoreRepository 文件中找到 誰創建的DBContext
查看 IDbContextProvider 默認實現是 UnitOfWorkDbContextProvider,如下圖,找到了。“GetDbContextAsync”方法創建的DBContext,接下來重構這個方法,當DBContext創建完成後,立即執行“RAGMA foreign_keys = ON”sql命令
3. 重寫 GetDbContextAsync 方法
思路:創建一個新類,繼承 UnitOfWorkDbContextProvider ,然後重寫 GetDbContextAsync 方法 ,再然後替換服務中註冊的 IDbContextProvider 的實現類
代碼如下:
查看代碼
public class xxxxxxfdsafdas<TDbContext> : UnitOfWorkDbContextProvider<TDbContext>
where TDbContext : IEfCoreDbContext
{
public xxxxxxfdsafdas(IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
ICancellationTokenProvider cancellationTokenProvider,
ICurrentTenant currentTenant,
IEfCoreDbContextTypeProvider efCoreDbContextTypeProvider)
: base(unitOfWorkManager, connectionStringResolver, cancellationTokenProvider, currentTenant, efCoreDbContextTypeProvider)
{
}
public override async Task<TDbContext> GetDbContextAsync()
{
var dbContext = await base.GetDbContextAsync();
var sql = FormattableStringFactory.Create("PRAGMA foreign_keys = ON");
await dbContext.Database.ExecuteSqlAsync(sql);
return dbContext;
}
}
類名稱自己寫一個,我這裏隨便寫下
服務替換
context.Services.Replace(new ServiceDescriptor(typeof(IDbContextProvider<>),
typeof(xxxxxxfdsafdas<>), ServiceLifetime.Transient));
OK,搞定