当前位置:网站首页>Data Filters in ABP
Data Filters in ABP
2022-08-11 00:54:00 【dotNET cross-platform】
本文首先介绍了ABPBuilt-in soft delete filter(ISoftDelete)and multitenancy filter(IMultiTenant),Then describes how to implement a custom filter,Finally, the practical problems encountered in the software development process are introduced,At the same time, it gives a not necessarily optimal idea to solve the problem.
一.预定义过滤器
ABPThe data filter source code inVolo.Abp.Data[2]包中,官方定义了2out-of-the-box filters,soft delete filter(ISoftDelete)and multitenancy filter(IMultiTenant),I'm sure everyone likes this2A built-in filter is already familiar.The following focuses on passingIDataFilterImplement local filtering,和通过AbpDataFilterOptionsImplement global filtering.
1.IDataFilter局部过滤
主要的思路就是通过IDataFilter依赖注入,然后通过_dataFilter.Disable<XXX>()Temporarily enable or disable filters:
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();
}
}
}
}This will locallyIsDeleted=1的记录查找出来.
2.AbpDataFilterOptions全局过滤
Mainly via options(Options)way to configure global filtering:
Configure<AbpDataFilterOptions>(options =>
{
options.DefaultStates[typeof(ISoftDelete)] = new DataFilterState(isEnabled: false);
});So it will be globallyIsDeleted=1的记录查找出来.其中的一个问题是,Where is this code written??I wrote it myselfXXX.Host->XXXHostModule->ConfigureServices中,比如Business.Host->BusinessHostModule->ConfigureServices.
二.自定义过滤器
Custom filters are relatively simple,It's basically eight-part format.,对于EFCore来说,就是重写DbContext中的ShouldFilterEntity和CreateFilterExpression方法.因为暂时用不到MongoDB,所以不做介绍,有兴趣可以参考[1],也不是很难.The following is an example to introduceEF Core的自定义过滤器.
1.定义过滤器接口
First define a filter interface,然后实现该接口:
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;
} Suddenly look good like this custom filters complex,Then think about theABPBuilt-in soft delete filter(ISoftDelete)and multitenancy filter(IMultiTenant)是如何实现的呢?然后就找到了源码ABP/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs:
After reading the source code implementation, you will find that the format is exactly the same,So custom filters are not that complicated to use.
三.遇到的实际问题
假如在SaaS系统中,There is a concept of main center and sub-center,什么意思呢?That is, you can see all the sub-centers in the main center.User数据,At the same time the main centre can put some general information(比如,科普文章)Share to branch.在ABPThe group asked,Some suggest that the host is the host,for tenant management,Can't see it as a tenant,This is a question of a father and son tenants.It is suggested that to get a copy of tenantsID过滤器,This can solve the problem with the curve,Without departing from the principle of host and tenant.Father and son tenants heard for the first time,所以暂不考虑.Because the system has been developed in part,If every entity inherits fake tenantID过滤器接口,So also feel trouble.
Finally choose to regard the main center as the host user,Sub-centers as tenants.For some general information(比如,科普文章),Directly in CRUDIDataFilter局部过滤.For example, the search implementation is as follows:
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);
}
}对于"All sub-centers can be seen in the main centerUser数据"这个问题,because it's just about viewing,不做增删改,所以又新建了一个User查找接口,directly in this interfaceIDataFilter局部过滤.这样新建的UserFind the interface to see the data of all sub-centers,原来的UserLookup interface can only see the host or tenant'sUser数据.总之,The architecture that suits your needs is the best,If the architecture does not meet the requirements,Then iterate the architecture.
参考文献:
[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]详解ABPThe use of data filters and data transfer objects in the framework: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
边栏推荐
猜你喜欢

③ 关系数据库标准语言SQL 数据查询(SELECT)

嵌入式软件打log的一些心得

rhel7.0解决yum无法使用(system is not registered to Red Hat Subscription Management)

YOLOv5的Tricks | 【Trick13】YOLOv5的detect.py脚本的解析与简化

How to do patent mining, the key is to find patent points, in fact, it is not too difficult

J9 Digital Theory: DAO governance is more like an ecological process: governance is native to the network and continues to evolve

Two-dimensional array combat project -------- "Minesweeper Game"

单片机人机交互--矩阵按键

SQL statement--get database table information, table name, column name, description comment, etc.

Apache Commons Configuration Remote Code Execution Vulnerability (CVE-2022-33980) Analysis & Reproduction
随机推荐
[GXYCTF2019]BabySQli
sed of the Three Musketeers of Shell Programming
WebView2 通过 PuppeteerSharp 实现RPA获取壁纸 (案例版)
16. 最接近的三数之和
ADC和DAC记录
C#使用计时器
networkmanager无法打开
"NIO Cup" 2022 Nioke Summer Multi-School Training Camp 2 DGHJKL Problem Solution
什么是“门”电路(电子硬件)
Analysis of LENS CRA and SENSOR CRA Matching Problems
Single-chip human-computer interaction--matrix key
BEVDepth: Acquisition of Reliable Depth for Multi-view 3D Object Detection Paper Notes
MSTP——多生成树(案列+配置)
C# JObject解析JSON数据
虚拟电厂可视化大屏,深挖痛点精准减碳
① 数据库介绍 及 关系型数据库的关系代数表达式
MySQL进阶查询
J9数字论:DAO治理更像一种生态过程:治理原生于网络,不断演变
How to determine the size of the version number
编程技巧│selenium 更新 chromedriver 驱动