diff --git a/docs/en/Data-Filtering.md b/docs/en/Data-Filtering.md index 7dfac258eb..be1d922fbd 100644 --- a/docs/en/Data-Filtering.md +++ b/docs/en/Data-Filtering.md @@ -255,7 +255,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) ABP abstracts the `IMongoDbRepositoryFilterer` interface to implement data filtering for the [MongoDB Integration](MongoDB.md), it works only if you use the repositories properly. Otherwise, you should manually filter the data. -Currently, the best way to implement a data filter for the MongoDB integration is to create a derived class of `MongoDbRepositoryFilterer` and override `AddGlobalFilters`. Example: +Currently, the best way to implement a data filter for the MongoDB integration is to create a derived class of `MongoDbRepositoryFilterer` and override `FilterQueryable`. Example: ````csharp [ExposeServices(typeof(IMongoDbRepositoryFilterer))] @@ -268,14 +268,14 @@ public class BookMongoDbRepositoryFilterer : MongoDbRepositoryFilterer> filters) + public override TQueryable FilterQueryable(TQueryable query) { - base.AddGlobalFilters(filters); - if (DataFilter.IsEnabled()) { - filters.Add(Builders.Filter.Eq(e => ((IIsActive)e).IsActive, true)); + return (TQueryable)query.Where(x => x.IsActive); } + + return base.FilterQueryable(query); } } ```` diff --git a/docs/zh-Hans/Data-Filtering.md b/docs/zh-Hans/Data-Filtering.md index 74192cf426..b17a4ecf9b 100644 --- a/docs/zh-Hans/Data-Filtering.md +++ b/docs/zh-Hans/Data-Filtering.md @@ -190,7 +190,7 @@ protected override Expression> CreateFilterExpression))] @@ -203,14 +203,14 @@ public class BookMongoDbRepositoryFilterer : MongoDbRepositoryFilterer> filters) + public override TQueryable FilterQueryable(TQueryable query) { - base.AddGlobalFilters(filters); - if (DataFilter.IsEnabled()) { - filters.Add(Builders.Filter.Eq(e => ((IIsActive)e).IsActive, true)); + return (TQueryable)query.Where(x => x.IsActive); } + + return base.FilterQueryable(query); } } ```` diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs index a40329240b..1fff832d76 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using MongoDB.Driver; using Volo.Abp.Domain.Entities; @@ -8,6 +9,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB; public interface IMongoDbRepositoryFilterer where TEntity : class, IEntity { Task AddGlobalFiltersAsync(List> filters); + + TQueryable FilterQueryable(TQueryable query) where TQueryable : IQueryable; } public interface IMongoDbRepositoryFilterer : IMongoDbRepositoryFilterer where TEntity : class, IEntity diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 9180b80b2c..58f5c72716 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -4,7 +4,6 @@ using MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Dynamic.Core; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -99,6 +98,8 @@ public class MongoDbRepository public IMongoDbBulkOperationProvider BulkOperationProvider => LazyServiceProvider.LazyGetService(); + public IMongoDbRepositoryFilterer RepositoryFilterer => LazyServiceProvider.LazyGetService>(); + public MongoDbRepository(IMongoDbContextProvider dbContextProvider) { DbContextProvider = dbContextProvider; @@ -738,6 +739,15 @@ public class MongoDbRepository { throw new AbpDbConcurrencyException("Database operation expected to affect 1 row but actually affected 0 row. Data may have been modified or deleted since entities were loaded. This exception has been thrown on optimistic concurrency check."); } + + protected override TQueryable ApplyDataFilters(TQueryable query) + { + if (typeof(TOtherEntity) == typeof(TEntity)) + { + return base.ApplyDataFilters((TQueryable)RepositoryFilterer.FilterQueryable(query.As>())); + } + return base.ApplyDataFilters(query); + } } public class MongoDbRepository @@ -746,7 +756,7 @@ public class MongoDbRepository where TMongoDbContext : IAbpMongoDbContext where TEntity : class, IEntity { - public IMongoDbRepositoryFilterer RepositoryFilterer { get; set; } + public IMongoDbRepositoryFilterer RepositoryFiltererWithKey => LazyServiceProvider.LazyGetService>(); public MongoDbRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) @@ -798,13 +808,23 @@ public class MongoDbRepository await DeleteManyAsync(entities, autoSave, cancellationToken); } + protected override TQueryable ApplyDataFilters(TQueryable query) + { + if (typeof(TOtherEntity) == typeof(TEntity)) + { + return base.ApplyDataFilters((TQueryable)RepositoryFiltererWithKey.FilterQueryable(query.As>())); + } + + return base.ApplyDataFilters(query); + } + protected async override Task> CreateEntityFilterAsync(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null) { - return await RepositoryFilterer.CreateEntityFilterAsync(entity, withConcurrencyStamp, concurrencyStamp); + return await RepositoryFiltererWithKey.CreateEntityFilterAsync(entity, withConcurrencyStamp, concurrencyStamp); } protected async override Task> CreateEntitiesFilterAsync(IEnumerable entities, bool withConcurrencyStamp = false) { - return await RepositoryFilterer.CreateEntitiesFilterAsync(entities, withConcurrencyStamp); + return await RepositoryFiltererWithKey.CreateEntitiesFilterAsync(entities, withConcurrencyStamp); } } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs index 451d30f0da..83063dae4c 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs @@ -36,6 +36,11 @@ public class MongoDbRepositoryFilterer : IMongoDbRepositoryFilterer(TQueryable query) where TQueryable : IQueryable + { + return query; + } } public class MongoDbRepositoryFilterer : MongoDbRepositoryFilterer, @@ -99,4 +104,9 @@ public class MongoDbRepositoryFilterer : MongoDbRepositoryFiltere return Builders.Filter.And(filters); } + + public virtual TQueryable FilterQueryable(TQueryable query) where TQueryable : IQueryable + { + return query; + } } diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MongoDbRepositoryFilterer_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MongoDbRepositoryFilterer_Tests.cs new file mode 100644 index 0000000000..059a0103d7 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/MongoDbRepositoryFilterer_Tests.cs @@ -0,0 +1,53 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Data; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MultiTenancy; +using Volo.Abp.TestApp.Domain; +using Xunit; + +namespace Volo.Abp.MongoDB.DataFiltering; + +[Collection(MongoTestCollection.Name)] +public class MongoDbAsyncQueryableProvider_Tests : MongoDbTestBase +{ + private readonly IRepository _personRepository; + + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddTransient, TestFilterQueryable>(); + base.AfterAddApplication(services); + } + + public MongoDbAsyncQueryableProvider_Tests() + { + _personRepository = GetRequiredService>(); + } + + [Fact] + public async Task Test() + { + var cities = await _personRepository.GetListAsync(); + cities.Count.ShouldBe(1); + cities[0].Name.ShouldBe("Istanbul"); + } +} + +public class TestFilterQueryable : MongoDbRepositoryFilterer +{ + public TestFilterQueryable( + IDataFilter dataFilter, + ICurrentTenant currentTenant) : + base(dataFilter, currentTenant) + { + } + + public override TQueryable FilterQueryable(TQueryable query) + { + return (TQueryable)query.Where(p => p.Name == "Istanbul"); + } +}