我们在数据库开发中,一般会运用软删除 (soft delete)模式 ,即不直接从数据库删除数据 ,而是标记这笔数据为已删除。因此 ,如果实体被软删除了,那么它就应该不会在应用程序中被检索到。要达到这种效果 ,我们需要在每次检索实体的查询语句上添加 SQL的 Where条件 IsDeleted = false 。这是个乏味的工作 。但它是个容易被忘掉的事情。因此 ,我们应该要有个自动的机制来处理这些问题 。
ABP 提供数据过滤器 (Data filters),它使用 自动化的,基于规则的过滤查询。
 
ABP已做好的过滤器
ISoftDelete
publicclass Person : Entity, ISoftDelete
{
publicvirtualstring Name { get; set; } publicvirtualbool IsDeleted { get; set; }
}

如上面的Person类,实现了ISoftDelete接口,当我们使用IRepository.Delete方法删除一个Person时,该Person并不真的从数据库删除,仅仅是IsDeleted属性被设置为true。

publicclass MyService
{
privatereadonly IRepository<Person> _personRepository; publicMyService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
} public List<Person> GetPeople()
{
return _personRepository.GetAllList();
}
}
GetPeople method only gets Person entities which has IsDeleted = false (not deleted). All repository methods and also navigation properties properly works. We could add some other Where conditions, joins.. etc. It will automatically add IsDeleted = false condition properly to the generated SQL query.

如上面代码,如果某个Person已经被软删除,那么使用IRepository获取所有Person数据时,过滤器会自动过滤掉已经软删除的Person,也就是说,GetAll不是获取实际上数据库还存有的所用Person数据,而是排除了之前被软删除的数据了。

A side note: If you implement IDeletionAudited (which extends ISoftDelete) then deletion time and deleter user id are also automatically set by ASP.NET Boilerplate.
 
IMustHaveTenant
publicclass Product : IMustHaveTenant
{
publicvirtualint TenantId { get; set; } publicvirtualstring Name { get; set; }
}

如果你创建了一个多租户的应用程序(储存所有租户的数据于单一一个数据库中),你肯定不会希望某个租户看到其他租户的资料,此时你可以实现IMustHaveTenant接口。

ABP会使用IABPSession来取得当前TenantId并且自动地替当前租户进行过滤查询处理。
If current user is not logged in to the system or current user is a host user (Host user is an upper level user that can manage tenants and tenant datas), ASP.NET Boilerplate automatically disables IMustHaveTenant filter. Thus, all data of all tenant's can be retrieved to the application. Notice that this is not about security, you should always authorize sensitive data.
 
IMayHaveTenant
publicclass Product : IMayHaveTenant
{
publicvirtualint? TenantId { get; set; } publicvirtualstring Name { get; set; }
}
If an entity class shared by tenants and the host (that means an entity object may be owned by a tenant or the host), you can use IMayHaveTenant filter.

IMayHaveTenant接口定义了TenantId,但是注意它是int?类型,可为空。

null value means this is a host entity, a non-null value means this entity owned by a tenant which's Id is the TenantId. ASP.NET Boilerplate uses IAbpSession to get current TenantId. IMayHaveTenant filter is not common as much as IMustHaveTenant. But you may need it for common structures used by host and tenants.
 
禁用过滤器
var people1 = _personRepository.GetAllList();

using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
{
var people2 = _personRepository.GetAllList();
} var people3 = _personRepository.GetAllList();
启用过滤器
也就是使用_unitOfWorkManager.Current.EnableFilter方法
 
设定过滤器参数
CurrentUnitOfWork.SetFilterParameter("PersonFilter", "personId", 42);
CurrentUnitOfWork.SetFilterParameter(AbpDataFilters.MayHaveTenant, AbpDataFilters.Parameters.TenantId, 42);
自定义过滤器
 

首先定义一个接口:

publicinterface IHasPerson
{
int PersonId { get; set; }
}

实现接口:

publicclass Phone : Entity, IHasPerson
{
[ForeignKey("PersonId")]
publicvirtual Person Person { get; set; }
publicvirtualint PersonId { get; set; } publicvirtualstring Number { get; set; }
}

重写DbContext类中的OnModelCreating 方法(用的EntityFramework.DynamicFilters,参考https://github.com/jcachat/EntityFramework.DynamicFilters):

protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); modelBuilder.Filter("PersonFilter", (IHasPerson entity, int personId) => entity.PersonId == personId, 0);
}

"PersonFilter" is the unique name of the filter here. Second parameter defines filter interface and personId filter parameter (not needed if filter is not parametric), last parameter is the default value of the personId.

最后,我们要把过滤器注册到ABP的工作单元系统中,以下代码需要写在模块的Preinitialize方法里:

Configuration.UnitOfWork.RegisterFilter("PersonFilter", false);

First parameter is same unique name we defined before. Second parameter indicates whether this filter is enabled or disabled by default. After declaring such a parametric filter, we can use it by supplying it's value on runtime.

using (CurrentUnitOfWork.EnableFilter("PersonFilter"))
{
CurrentUnitOfWork.SetFilterParameter("PersonFilter", "personId", 42);
var phones = _phoneRepository.GetAllList();
//...
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ABP的数据过滤器(Data Filters)的更多相关文章

  1. ABP(现代ASP.NET样板开发框架)系列之13、ABP领域层——数据过滤器(Data filters)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之13.ABP领域层——数据过滤器(Data filters) ABP是“ASP.NET Boilerplate P ...

  2. ABP中的数据过滤器

      本文首先介绍了ABP内置的软删除过滤器(ISoftDelete)和多租户过滤器(IMultiTenant),然后介绍了如何实现一个自定义过滤器,最后介绍了在软件开发过程中遇到的实际问题,同时给出了 ...

  3. ABP理论学习之数据过滤器

    返回总目录 本篇目录 介绍 预定义过滤器 关闭过滤器 开启过滤器 设置过滤器参数 定义自定义过滤器 其他ORM 介绍 软删除模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除 ...

  4. ABP官方文档翻译 3.8 数据过滤器

    数据过滤器 介绍 预定义过滤器 ISoftDelete 何时使用? IMustHaveTenant 何时使用? IMayHaveTenant 何时使用 禁用过滤器 关于using语句 关于多租户 全局 ...

  5. ABP 配置全局数据过滤器

    ABP官方数据过滤的地址:https://aspnetboilerplate.com/Pages/Documents/Data-Filters 中文可以看这个:https://aspnetboiler ...

  6. 文章翻译:ABP如何在EF core中添加数据过滤器

    原文地址:https://aspnetboilerplate.com/Pages/Documents/Articles%5CHow-To%5Cadd-custom-data-filter-ef-cor ...

  7. 第一章、VUE-挂载点-实例成员-数据-过滤器-文本指令-事件指令-属性指令-表单指令-01

    目录 路飞项目 vue vue 导读 vue 的优势 渐进式框架 引入 vue 实例成员 - 挂载点 el js 对象(字典)补充 实例成员 - 数据 data 实例成员 - 过滤器 filters ...

  8. VUE-挂载点-实例成员-数据-过滤器-文本指令-事件指令-属性指令-表单指令-01

    目录 路飞项目 vue vue 导读 vue 的优势 渐进式框架 引入 vue 实例成员 - 挂载点 el js 对象(字典)补充 实例成员 - 数据 data 实例成员 - 过滤器 filters ...

  9. C# Web 数据注解Data Annotations、模型状态ModelState、数据验证

    C#中的模型状态与数据注解,为我们提供了很便利的请求数据的验证. 1. ModelState ModelState在进行数据验证的时候很有用的,它是: 1)验证数据,以及保存数据对应的错误信息. 2) ...

随机推荐

  1. 约瑟夫环(Josehpuse)的模拟

    约瑟夫环问题: 0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里剩下的最后一个数字. 这里给出以下几种解法, 1.用队列模拟 每次将前m-1个元 ...

  2. (C#) Tasks 中的异常处理(Exception Handling.)

    多线程编程中要注意对线程异常的处理.首先写个例子. 一个线程用于显示信息(Show Messages).主线程用于做其他工作(Do Works). using (Task taskShowMessag ...

  3. ADF_Desktop Integration系列4_ADF桌面集成入门之部署ADF Desktop Excel

    2013-05-01 Created By BaoXinjian

  4. 112、两个Activity切换黑屏问题

    <activity android:name=".main.select.ActDoyenActivity" android:screenOrientation=" ...

  5. Sonar升级遇到的那些事儿

    目录 背景 如何升级 如何回滚 问题解决 参考 背景 目前我们用SonarQube版本是4.0,这次准备升级到最新版本5.1, 以便支持以后的JavaScript的项目. 如何升级 我们可以直接跨越版 ...

  6. android studio新项目时提示:Plugin is too old, please update to a more recent version

    今天想写一个程序来测试一下android studo代码,但是创建好项目后,提示: Error:(1, 0) Plugin is too old, please update to a more re ...

  7. 解决:jquery ajax非首次请求Server端获取cookie值中文乱码问题

    HttpCookie cookie = new HttpCookie("RealName", HttpUtility.UrlEncode("你想要设置的值")) ...

  8. inline-block和block的区别

    <html> <head> <style> body,ul,li,span{padding:0px;margin:0px;} </style> < ...

  9. 在 Visual Studio Code 中使用 PoweShell - CodeShell

    一直希望在 Visual Studio Code 中使用 PowerShell,插件 CodeShell 提供了对于 PowerShell 的支持. 安装 首先按 F1,打开命令窗口,输入安装插件的命 ...

  10. Sum of Two integers

    两个整数相加不能用加减 用位运算 假设两整数a=2和b=6,它们的二进制表示分别为010和110 sum=a^b表示两个二进制数相加不考虑进位: 010 ^  110 =  100 carry=(a& ...