当前位置:网站首页>ABP中的数据过滤器 (转载非原创)
ABP中的数据过滤器 (转载非原创)
2022-08-09 12:21:00 【wxilejun】
本文首先介绍了ABP内置的软删除过滤器(ISoftDelete)和多租户过滤器(IMultiTenant),然后介绍了如何实现一个自定义过滤器,最后介绍了在软件开发过程中遇到的实际问题,同时给出了解决问题的一个未必最优的思路。
一.预定义过滤器
ABP中的数据过滤器源码在Volo.Abp.Data[2]包中,官方定义了2个开箱即用的过滤器,分别是软删除过滤器(ISoftDelete)和多租户过滤器(IMultiTenant),想必大家对这2个内置的过滤器已经比较熟悉了。下面重点说下通过IDataFilter实现局部过滤,和通过AbpDataFilterOptions实现全局过滤。
1.IDataFilter局部过滤
主要的思路就是通过IDataFilter依赖注入,然后通过_dataFilter.Disable<XXX>()
临时的启用或者禁用过滤器:
namespace Acme.BookStore
{
public class MyBookService : ITransientDependency
{
private readonly IDataFilter _dataFilter;
private readonly IRepository<Book, Guid> _bookRepository;
public MyBookService(IDataFilter dataFilter, IRepository<Book, Guid> bookRepository)
{
_dataFilter = dataFilter;
_bookRepository = bookRepository;
}
public async Task<List<Book>> GetAllBooksIncludingDeletedAsync()
{
// 临时禁用ISoftDelete过滤器
using (_dataFilter.Disable<ISoftDelete>())
{
return await _bookRepository.GetListAsync();
}
}
}
}
这样就会局部地把IsDeleted=1的记录查找出来。
2.AbpDataFilterOptions全局过滤
主要是通过选项(Options)的方式来配置全局过滤:
Configure<AbpDataFilterOptions>(options =>
{
options.DefaultStates[typeof(ISoftDelete)] = new DataFilterState(isEnabled: false);
});
这样就会全局地把IsDeleted=1的记录查找出来。其中的一个问题是,这段代码写到哪里呢?自己是写到XXX.Host->XXXHostModule->ConfigureServices中,比如Business.Host->BusinessHostModule->ConfigureServices。
二.自定义过滤器
自定义过滤器是比较简单的,基本上都是八股文格式了,对于EFCore来说,就是重写DbContext中的ShouldFilterEntity和CreateFilterExpression方法。因为暂时用不到MongoDB,所以不做介绍,有兴趣可以参考[1],也不是很难。下面通过一个例子来介绍下EF Core的自定义过滤器。
1.定义过滤器接口
首先定义一个过滤器接口,然后实现该接口:
public interface IIsActive
{
bool IsActive { get; }
}
public class Book : AggregateRoot<Guid>, IIsActive
{
public string Name { get; set; }
public bool IsActive { get; set; } //Defined by IIsActive
}
2.重写DbContext中的方法
然后就是重写DbContext中的ShouldFilterEntity和CreateFilterExpression方法:
protected bool IsActiveFilterEnabled => DataFilter?.IsEnabled<IIsActive>() ?? false;
protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType)
{
if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity)))
{
return true;
}
return base.ShouldFilterEntity<TEntity>(entityType);
}
protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
{
var expression = base.CreateFilterExpression<TEntity>();
if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity)))
{
Expression<Func<TEntity, bool>> isActiveFilter = e => !IsActiveFilterEnabled || EF.Property<bool>(e, "IsActive");
expression = expression == null ? isActiveFilter : CombineExpressions(expression, isActiveFilter);
}
return expression;
}
突然看上去觉得这个自定义过滤器好复杂,后来想想那ABP内置的软删除过滤器(ISoftDelete)和多租户过滤器(IMultiTenant)是如何实现的呢?然后就找到了源码ABP/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
:
看了源码实现后会发现格式一模一样,所以自定义过滤器使用起来没有这么复杂。
三.遇到的实际问题
假如在SaaS系统中,有一个主中心和分中心的概念,什么意思呢?就是在主中心中可以看到所有分中心的User数据,同时主中心可以把一些通用的资料(比如,科普文章)共享给分中心。在ABP群里问了下,有人建议宿主就是宿主,用来做租户管理的,不能把它当成一个租户,这是一个父子租户的问题。有人建议搞一个仿租户ID过滤器,这样既能曲线解决问题,又不背离宿主和租户的原则。父子租户第一次听说,所以暂不考虑。因为系统已经开发了一部分,如果每个实体都继承仿租户ID过滤器接口,那么也觉得麻烦。 最终选择把主中心当成是宿主用户,分中心当成是租户。对于一些通用的资料(比如,科普文章),在增删改查中直接IDataFilter局部过滤。比如查找实现如下:
public async Task<PagedResultDto<ArticleDto>> GetAll(GetArticleInputDto input)
{
// 临时禁用掉IMultiTenant过滤器
using (_dataFilter.Disable<IMultiTenant>())
{
var query = (await _repository.GetQueryableAsync()).WhereIf(!string.IsNullOrWhiteSpace(input.Filter), a => a.Title.Contains(input.Filter));
var totalCount = await query.CountAsync();
var items = await query.OrderBy(input.Sorting ?? "Id").Skip(input.SkipCount).Take(input.MaxResultCount).ToListAsync();
var dto = ObjectMapper.Map<List<Article>, List<ArticleDto>>(items);
return new PagedResultDto<ArticleDto>(totalCount, dto);
}
}
对于"主中心中可以看到所有分中心的User数据"这个问题,因为只是涉及到查看,不做增删改,所以又新建了一个User查找接口,在该接口中直接IDataFilter局部过滤。这样新建的User查找接口就可以看到所有分中心的数据,原来的User查找接口仅能看到宿主或者租户的User数据。总之,适合自己需求的架构就是最好的,如果架构满足不了需求了,那么就迭代架构。
参考文献: [1]数据过滤:https://docs.abp.io/zh-Hans/abp/6.0/Data-Filtering [2]Volo.Abp.Data:https://github.com/abpframework/abp/tree/dev/framework/src/Volo.Abp.Data [3]EntityFramework.DynamicFilters:https://github.com/zzzprojects/EntityFramework.DynamicFilters [4]ABP文档笔记 - 数据过滤:https://www.cnblogs.com/wj033/p/6494879.html [5]ABP领域层 - 数据过滤器:https://www.kancloud.cn/gaotang/abp/225839 [6]Mastering-ABP-Framework:https://github.com/PacktPublishing/Mastering-ABP-Framework [7]ABP多租户:https://docs.abp.io/zh-Hans/abp/6.0/Multi-Tenancy [8]ASP.NET Boilerplate中文文档:https://www.kancloud.cn/gaotang/abp/225819 [9]详解ABP框架中数据过滤器与数据传输对象使用:https://wenku.baidu.com/view/ec237e90b3717fd5360cba1aa8114431b80d8e5e [10]ASP.NET Boilerplate官方文档:https://aspnetboilerplate.com/Pages/Documents/Introduction [11]How to create a custom data filter with EF Core:https://support.aspnetzero.com/QA/Questions/4752/How-to-create-a-custom-data-filter-with-EF-Core
转载来源: https://www.cnblogs.com/shengshengwang/p/16564270.html
边栏推荐
- How should the acceptance criteria for R&D requirements be written?| Agile Practices
- #物联网征文#小熊派设备开发实战
- About the handling of variable parameters in the Retrofit network request URL
- The redis library cannot be imported
- Byte Qiu Zhao confused me on both sides, and asked me under what circumstances would the SYN message be discarded?
- 二叉树的序列化和反序列化
- Flutter入门进阶之旅(四)文本输入Widget TextField
- 脱光衣服待着就能减肥,当真有这好事?
- The core key points of microservice architecture
- 数据挖掘-05
猜你喜欢
Too much volume... Tencent was asked on the side that the memory was full, what would happen?
又有大厂员工连续加班倒下/ 百度搜狗取消快照/ 马斯克生父不为他骄傲...今日更多新鲜事在此...
Report: The number of students who want to learn AI has increased by 200%, and there are not enough teachers
曼城推出可检测情绪的智能围巾,把球迷给整迷惑了
WeChat side: what is consistent hashing, usage scenarios, and what problems does it solve?
MySQL 原理与优化,Group By 优化 技巧
两个链表相加
中断系统结构及中断控制详解
鹅厂机器狗花式穿越10m梅花桩:前空翻、单桩跳、起身作揖...全程不打一个趔趄...
智驾科技完成C1轮融资,此前2轮已融4.5亿元
随机推荐
WebView injects Js code to realize large image adaptive screen click image preview details
Two minutes recording can pass by second language!The volcano how to practice and become voice tone reproduction technology?
ansible-cmdb friendly display ansible collects host information
WeChat side: what is consistent hashing, usage scenarios, and what problems does it solve?
900页数学论文证明旋转的黑洞不会爆炸,丘成桐:30多年来广义相对论首次重大突破...
批量读取word docx文件指定表格内容,保存在excel文件中
西湖大学教授怎么看AI制药革命?|量子位智库圆桌实录
WeChat Mini Program Payment and Refund Overall Process
AQS同步组件-FutureTask解析和用例
2022牛客多校(六)M. Z-Game on grid
中断系统结构及中断控制详解
位图与位运算
Common gadgets of Shell (sort, uniq, tr, cut)
放下手机吧:实验表明花20分钟思考和上网冲浪同样快乐
【HCIP持续更新】IS-IS协议原理与配置
1小时直播招募令:行业大咖干货分享,企业报名开启丨量子位·视点
Flutter入门进阶之旅(十)Dialog&Toast
数据挖掘-05
使用RecyclerView实现三级折叠列表
The FFmpeg library is configured and used on win10 (libx264 is not configured)