@
回收站是當用戶刪除一條記錄時,不是直接從資料庫中刪除,而是將其放入「回收站」,以便使用者可以在需要時恢復資料。
在Abp框架中,若實體實現了ISoftDelete,則將實體標記為刪除時不是物理刪除,而是「軟刪除」
public interface ISoftDelete
{
/// <summary>
/// Used to mark an Entity as 'Deleted'.
/// </summary>
bool IsDeleted { get; set; }
}
當使用倉儲刪除一條記錄時,ABP會自動將 IsDeleted 設定為true,並將刪除操作替換為修改操作。 在查詢資料庫時會自動過濾軟刪除的實體。
利用這個原理,可以將「軟刪除」行為認為是放入了「回收站」,而將「恢復」行為認為是從「回收站」中取出。將記錄硬刪除的行為認為是「永久刪除」, 將全部已「軟刪除」的記錄硬刪除,則是「清空回收站」
因此我需要實現一個自定義過濾器,用於檢視已刪除的實體。
定義僅檢視軟刪除的過濾器,命名"OnlyShowSoftDelete"
public class FileDataFilters
{
public const string OnlyShowSoftDelete = "OnlyShowSoftDelete";
}
在模組中註冊過濾器,isEnabledByDefault引數為false,預設不啟用
Configuration.UnitOfWork.RegisterFilter(FileDataFilters.OnlyShowSoftDelete, false);
在DbContext中,增加IsOnlyShowSoftDeleteFilterEnabled屬性,用於判斷當前的查詢上下文中是否啟用了「僅檢視軟刪除」過濾器
public bool IsOnlyShowSoftDeleteFilterEnabled => CurrentUnitOfWorkProvider?.Current?.IsFilterEnabled(FileStorage.Uow.FileDataFilters.OnlyShowSoftDelete) == true;
在DbContext中,重寫CreateFilterExpression方法,當啟用了「僅檢視軟刪除」過濾器時,自動過濾軟刪除的實體
protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
{
var expression = base.CreateFilterExpression<TEntity>();
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
Expression<Func<TEntity, bool>> softDeleteFilter = e => !IsOnlyShowSoftDeleteFilterEnabled || ((ISoftDelete)e).IsDeleted;
expression = expression == null ? softDeleteFilter : CombineExpressions(expression, softDeleteFilter);
}
return expression;
}
查詢正常業務時,不需要對預設的過濾器做操作。
在檢視「回收站」中的資料時,需要關閉AbpDataFilters.SoftDelete過濾器,開啟FileDataFilters.OnlyShowSoftDelete過濾器。
在使用倉儲做任何查詢(如: GetAll或Get)之前,加入以下程式碼:
UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete);
UnitOfWorkManager.Current.EnableFilter(FileDataFilters.OnlyShowSoftDelete);
在刪除記錄時,通過呼叫倉儲的Delete()方法,將記錄放入「回收站」中。呼叫HardDelete()方法,將記錄永久刪除。
public virtual async Task DeleteAsync(File file, bool isHardDelete = false)
{
if (isHardDelete)
{
await _repository.HardDeleteAsync(file); //永久刪除
}
else
{
await _repository.DeleteAsync(file); //放入「回收站」
}
}
獲取已經「軟刪除」的記錄,呼叫UnDelete()方法,將記錄從「回收站」中取出
UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete);
UnitOfWorkManager.Current.EnableFilter(FileDataFilters.OnlyShowSoftDelete);
var currentFile = await _repository.GetAsync(file.Id);
currentFile.UnDelete();
本文來自部落格園,作者:林曉lx,轉載請註明原文連結:https://www.cnblogs.com/jevonsflash/p/17567356.html