回到目錄 概念 ISoftDelete即軟刪除,數據在進行delete後不會從資料庫清除,而只是標記一個狀態,在業務範圍里都不能獲取到這個數據,這在ORM框架里還是比較容易實現的,對傳統的ado來說需要對sql統一進行攔截和條件過濾. 實施步驟 代碼實現 1 實體繼承ISoftDelete 2 數據 ...
概念
ISoftDelete即軟刪除,數據在進行delete後不會從資料庫清除,而只是標記一個狀態,在業務範圍里都不能獲取到這個數據,這在ORM框架里還是比較容易實現的,對傳統的ado來說需要對sql統一進行攔截和條件過濾.
實施步驟
- 實體繼承ISoftDelete
- 數據上下文實現對IsDeleted的過濾
- 對刪除方法進行調整,添加對ISoftDelete的支持
代碼實現
1 實體繼承ISoftDelete
protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { // 1. Add the IsDeleted property entityType.GetOrAddProperty("IsDeleted", typeof(bool)); // 2. Create the query filter var parameter = Expression.Parameter(entityType.ClrType); // 3. EF.Property<bool>(post, "IsDeleted") var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool)); var isDeletedProperty = Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted")); // 4. EF.Property<bool>(post, "IsDeleted") == false BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty, Expression.Constant(false)); // 5. post => EF.Property<bool>(post, "IsDeleted") == false var lambda = Expression.Lambda(compareExpression, parameter); modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda);
2 數據上下文實現對IsDeleted的過濾
public class ProductInfo : EntityBase, ISoftDelete { public string Title { get; set; } public decimal Amount { get; set; } public int Discount { get; set; } public int Inventory { get; set; } public DateTime DeletedDate { get; set; } public string DeletedUser { get; set; } public bool IsDeleted { get; set; } /// <summary> /// domain method /// </summary> /// <returns></returns> public decimal GetSaleAmount() { return Amount * Discount / 100; } }
3 對刪除方法進行調整,添加對ISoftDelete的支持
代碼來自Lind.DotNetCore.Repository.EFRepository類型
public void Delete(TEntity item) { if (item != null) { if (typeof(ISoftDelete).IsAssignableFrom(item.GetType())) { Db.Entry(item).State = EntityState.Modified; var delEntity = item as ISoftDelete; delEntity.DeletedDate = DateTime.Now; delEntity.IsDeleted = true; } else { //物理刪除 Db.Set<TEntity>().Attach(item as TEntity); Db.Entry(item).State = EntityState.Deleted; Db.Set<TEntity>().Remove(item as TEntity); } this.SaveChanges(); } }
上面幾行代碼實現了對軟刪除的完整支持,從ISoftDelete介面到數據上下文里的過濾IsDeleted,再到優化後的Delete()方法,一切看上去都很優雅!
對於軟刪除支持的框架也很多,像abp,eshopconationer,linddotnetcore等!
歡迎大家的閱讀與思考!