数据过滤

    ABP定义了一些开箱即用的过滤.

    实体标记为已删除,并不是物理删除. 实现 接口将你的实体”软删除”.

    示例:

    ISoftDelete 定义了 IsDeleted 属性. 当你使用删除一条记录时, ABP会自动将 IsDeleted 设置为true,并将删除操作替换为修改操作(如果需要,也可以手动将 IsDeleted 设置为true). 在查询数据库时会自动过滤软删除的实体.

    多租户 是创建 SaaS 应用程序的有效方法. 多租户应用程序通常需要在租户间隔离数据. 实现 IMultiTenant 接口使你的实体支持 “多租户”.

    示例:

    1. using System;
    2. using Volo.Abp;
    3. using Volo.Abp.Domain.Entities;
    4. using Volo.Abp.MultiTenancy;
    5. namespace Acme.BookStore
    6. {
    7. public class Book : AggregateRoot<Guid>, ISoftDelete, IMultiTenant
    8. {
    9. public string Name { get; set; }
    10. public bool IsDeleted { get; set; } //Defined by ISoftDelete
    11. public Guid? TenantId { get; set; } //Defined by IMultiTenant
    12. }
    13. }

    你可以使用 IDataFilter 服务控制数据过滤.

    示例:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Threading.Tasks;
    4. using Volo.Abp;
    5. using Volo.Abp.Data;
    6. using Volo.Abp.DependencyInjection;
    7. using Volo.Abp.Domain.Repositories;
    8. {
    9. public class MyBookService : ITransientDependency
    10. {
    11. private readonly IDataFilter _dataFilter;
    12. private readonly IRepository<Book, Guid> _bookRepository;
    13. IDataFilter dataFilter,
    14. IRepository<Book, Guid> bookRepository)
    15. {
    16. _dataFilter = dataFilter;
    17. _bookRepository = bookRepository;
    18. }
    19. public async Task<List<Book>> GetAllBooksIncludingDeletedAsync()
    20. {
    21. //Temporary disable the ISoftDelete filter
    22. using (_dataFilter.Disable<ISoftDelete>())
    23. {
    24. return await _bookRepository.GetListAsync();
    25. }
    26. }
    27. }
    28. }
    • IDataFilter 服务到你的类中.
    • using 语句中使用 Disable 方法创建一个代码块,其中禁用了 ISoftDelete 过滤器(始终与 using 搭配使用,确保代码块执行后将过滤重置为之前的状态).

    IDataFilter.Enable 方法可以启用过滤. 可以嵌套使用 EnableDisable 方法定义内部作用域.

    AbpDataFilterOptions 用于设置数据过滤系统选项.

    下面的示例代码在默认情况下禁用了 ISoftDelete 过滤,除非显示启用,在查询数据库时会包含标记为已删除的实体:

    定义和实现新的过滤很大程序上取决与数据库提供者. ABP为所有的数据库提供者实现了预构建的过滤.

    示例:

    1. public interface IIsActive
    2. {
    3. bool IsActive { get; }
    4. }

    IIsActive 接口可以过滤活跃/消极数据,任何都可以实现它:

    1. public class Book : AggregateRoot<Guid>, IIsActive
    2. {
    3. public bool IsActive { get; set; } //Defined by IIsActive
    4. }

    ABP使用EF Core的全局过滤系统用于. 所以它很好的集成到EF Core中,即使你直接使用 DbContext 它也可以正常工作.

    实现自定义过滤的最佳方法是为重写你的 的 ShouldFilterEntityCreateFilterExpression 方法. 示例:

    • 添加 IsActiveFilterEnabled 属性用于检查是否启用了 IIsActive . 内部使用了之前介绍到的 IDataFilter 服务.
    • 重写 ShouldFilterEntityCreateFilterExpression 方法检查给定实体是否实现 IIsActive 接口,在必要时组合表达式.

    ABP直接在仓储级别实现数据过滤用于. 所以只有正确的使用仓储,它才会工作. 否则你需要手动过滤数据.

    目前为MongoDB集成实现数据过滤的最佳方法是重写派生自 MongoDbRepository 仓储的 AddGlobalFilters 方法:

    1. public class BookRepository : MongoDbRepository<BookStoreMongoDbContext, Book, Guid>
    2. {
    3. protected override void AddGlobalFilters(List<FilterDefinition<Book>> filters)
    4. {
    5. if (DataFilter.IsEnabled<IIsActive>())
    6. {
    7. filters.Add(Builders<Book>.Filter.Eq(e => ((IIsActive)e).IsActive, true));
    8. }
    9. }
    10. }

    示例中仅为 Book 实体实现了过滤. 如果你想要为所有的实体实现过滤 (实现了 IIsActive 接口的实体),可以创建自己的MongoDB仓储基类并重 写 AddGlobalFilters 方法. 如下所示:

    1. public abstract class MyMongoRepository<TMongoDbContext, TEntity, TKey> : MongoDbRepository<TMongoDbContext, TEntity, TKey>
    2. where TMongoDbContext : IAbpMongoDbContext
    3. where TEntity : class, IEntity<TKey>
    4. {
    5. protected MyMongoRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
    6. : base(dbContextProvider)
    7. {
    8. }
    9. protected override void AddGlobalFilters(List<FilterDefinition<TEntity>> filters)
    10. {
    11. if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity))
    12. && DataFilter.IsEnabled<IIsActive>())
    13. {
    14. filters.Add(Builders<TEntity>.Filter.Eq(e => ((IIsActive)e).IsActive, true));
    15. }