利用Abp过滤器实现业务数据“回收站”功能
@
原理
回收站是当用户删除一条记录时,不是直接从数据库中删除,而是将其放入“回收站”,以便用户可以在需要时恢复数据。
在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();
利用Abp过滤器实现业务数据“回收站”功能的更多相关文章
- Excel文件 利用MySQL/Python 实现自动处理数据的功能
目录 问题描述: 解决方案: 一.SQL查询 二.SQL.python处理 三.python处理 四.优化python处理 1.手动执行代码 2.开机自动执行代码 对比四种方案: 总结: 问题描述: ...
- 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...
- vi的替换使用、如何让linux有回收站功能、系统重要文件、目录数据
1 vi的替换使用方法 vi使用的原理 (编辑文件会生成一个隐藏临时文件) 1.1 替换文件内容方法:vi (1)%s#oldboy#oldgirl#g --- 将oldboy全部替换为oldgi ...
- CI Weekly #16 | 从另一个角度看开发效率:flow.ci 数据统计功能上线
很开心的告诉大家,flow.ci 数据统计功能已正式上线. 进入 flow.ci 控制台,点击「数据分析」按钮,你可以按照时间日期筛选,flow.ci 将多维度地展示「组织与项目」的构建数据指标与模型 ...
- Vue单页面中进行业务数据的上报
为什么要在标题里加上一个业务数据的上报呢,因为在咱们前端项目中,可上报的数据维度太多,比如还有性能数据.页面错误数据.console捕获等.这里我们只讲解业务数据的埋点. 业务数据的上报主要分为: 各 ...
- 大数据学习day34---spark14------1 redis的事务(pipeline)测试 ,2. 利用redis的pipeline实现数据统计的exactlyonce ,3 SparkStreaming中数据写入Hbase实现ExactlyOnce, 4.Spark StandAlone的执行模式,5 spark on yarn
1 redis的事务(pipeline)测试 Redis本身对数据进行操作,单条命令是原子性的,但事务不保证原子性,且没有回滚.事务中任何命令执行失败,其余的命令仍会被执行,将Redis的多个操作放到 ...
- 解析大型.NET ERP系统 数据审计功能
数据审计,英语表达是Audit,是追踪数据变化的过程,记录数据变化前后的值,供参考分析.通过设置,ERP可以追踪一个表的所有字段的变化,也可以只记录指定的字段的值变化.欧美企业每年都有独立的审计部门, ...
- 在Winform开发框架中,利用DevExpress控件实现数据的快速录入和选择
在实际的项目开发过程中,有好的控件或者功能模块,我都是想办法尽可能集成到我的WInform开发框架中,这样后面开发项目起来,就可以节省很多研究时间,并能重复使用,非常高效方便.在我很早之前的一篇博客& ...
- P2P小贷网站业务数据流程分享
P2P小贷网站业务数据流程分享 引言 这是去年年底开发的一个项目,完成后和用户的衔接没有很好的做起来,所以项目就搁浅了.9月以来,看各路P2P风声水起,很是热闹:这里分享下我的设计文档,算是抛砖引玉, ...
- ASP.net(C#)利用SQL Server实现注册和登陆功能
说说我现在吧,楼主现在从事的事IT行业,主攻DotNet技术:当然这次上博客园我也是有备而来,所有再次奉献鄙人拙作,以飨诸位,望诸位不吝赐教. 世界上大多数的工作都是熟练性的工种,编程也不例外,做久了 ...
随机推荐
- Docker容器网络(基本网络模型)
解析Docker的4种容器网络 默认网络模型 先介绍默认的网络模型: 安装docker后,输入ifconfig就会发现多了网卡中多了一个docker0: $ ifconfig docker0: fla ...
- Pytorch实践模型训练(损失函数)
一个深度学习项目包括了: 模型设计.损失函数设计.梯度更新方法.模型保存和加载和模型训练,其中损失函数就像一把衡量模型学习效果的尺子,训练模型的过程就是优化损失函数的过程,模型拿到数据之后有一个非常重 ...
- 因果推断-Caual Inference
两种形式 Reduced Form:Let data speak itself,主要采用regression等方法 Structure Approach:Data only can never rev ...
- 你知道Object类和Objects的常用方法吗
文章目录 Object的常用方法 Objects的常用方法 hashCode hash isNull equals requireNonNull compare nonNull 大家好,Leo又来了! ...
- Mac M系列芯片 vue前端node-sass兼容问题解决
0.由于M系列芯片是arm架构,在使用brew安装node时都是arm的node,但是node-sass@4.14.1版本中不支持arm架构的出现如下报错: Error: Node Sass does ...
- JavaScript中的四种枚举方式
字符串和数字具有无数个值,而其他类型如布尔值则是有限的集合. 一周的日子(星期一,星期二,...,星期日),一年的季节(冬季,春季,夏季,秋季)和基本方向(北,东,南,西)都是具有有限值集合的例子. ...
- SVN添加新的用户
1.首先确定svn的文件夹的位置 find / -name svn 2.通过find找到svn地址之后,cd进入 /var/svn/ 下 cd /var/svn/ 3.修改/var/svn/下面的au ...
- RMQ问题ST表
稀疏表(Sparse Table表) 解决静态RMQ,区间最值查询问题的数据结构,树状数组(BIT)解决动态前缀和问题的数据结构: 例:https://www.luogu.org/problemnew ...
- 2021-12-14:根据身高重建队列。 假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个
2021-12-14:根据身高重建队列. 假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序).每个 people[i] = [hi, ki] 表示第 i 个 ...
- 2021-09-29:不同路径。一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为
2021-09-29:不同路径.一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 "Start" ).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右 ...