Browse Source

Make `IMongoDbRepositoryFilterer` async.

Resolve #11588
pull/11595/head
maliming 4 years ago
parent
commit
4c5a873fb8
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 11
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs
  2. 120
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  3. 25
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs

11
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepositoryFilterer.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Driver;
using Volo.Abp.Domain.Entities;
@ -6,14 +7,14 @@ namespace Volo.Abp.Domain.Repositories.MongoDB;
public interface IMongoDbRepositoryFilterer<TEntity> where TEntity : class, IEntity
{
void AddGlobalFilters(List<FilterDefinition<TEntity>> filters);
Task AddGlobalFiltersAsync(List<FilterDefinition<TEntity>> filters);
}
public interface IMongoDbRepositoryFilterer<TEntity, TKey> : IMongoDbRepositoryFilterer<TEntity> where TEntity : class, IEntity<TKey>
{
FilterDefinition<TEntity> CreateEntityFilter(TKey id, bool applyFilters = false);
Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TKey id, bool applyFilters = false);
FilterDefinition<TEntity> CreateEntityFilter(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null);
Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null);
/// <summary>
/// Creates filter for given entities.
@ -24,7 +25,7 @@ public interface IMongoDbRepositoryFilterer<TEntity, TKey> : IMongoDbRepositoryF
/// <param name="entities">Entities to be filtered.</param>
/// <param name="applyFilters">Set true to use GlobalFilters. Default is false.</param>
/// <returns>Created <see cref="FilterDefinition{TDocument}"/>.</returns>
FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TEntity> entities, bool applyFilters = false);
Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TEntity> entities, bool applyFilters = false);
/// <summary>
/// Creates filter for given ids.
@ -34,5 +35,5 @@ public interface IMongoDbRepositoryFilterer<TEntity, TKey> : IMongoDbRepositoryF
/// </remarks>
/// <param name="ids">Entity Ids to be filtered.</param>
/// <param name="applyFilters">Set true to use GlobalFilters. Default is false.</param>
FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TKey> ids, bool applyFilters = false);
Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TKey> ids, bool applyFilters = false);
}

120
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -2,7 +2,6 @@ using JetBrains.Annotations;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
@ -105,7 +104,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
DbContextProvider = dbContextProvider;
}
public override async Task<TEntity> InsertAsync(
public async override Task<TEntity> InsertAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -136,7 +135,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
return entity;
}
public override async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
public async override Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
@ -171,7 +170,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
}
}
public override async Task<TEntity> UpdateAsync(
public async override Task<TEntity> UpdateAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -202,7 +201,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
result = await collection.ReplaceOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: cancellationToken
);
@ -210,7 +209,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
else
{
result = await collection.ReplaceOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: cancellationToken
);
@ -224,7 +223,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
return entity;
}
public override async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
public async override Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entityArray = entities.ToArray();
@ -259,10 +258,10 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
BulkWriteResult result;
List<WriteModel<TEntity>> replaceRequests = new List<WriteModel<TEntity>>();
var replaceRequests = new List<WriteModel<TEntity>>();
foreach (var entity in entityArray)
{
replaceRequests.Add(new ReplaceOneModel<TEntity>(CreateEntityFilter(entity), entity));
replaceRequests.Add(new ReplaceOneModel<TEntity>(await CreateEntityFilterAsync(entity), entity));
}
var collection = dbContext.Collection<TEntity>();
@ -281,7 +280,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
}
}
public override async Task DeleteAsync(
public async override Task DeleteAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -304,7 +303,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
result = await collection.ReplaceOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: cancellationToken
);
@ -312,7 +311,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
else
{
result = await collection.ReplaceOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: cancellationToken
);
@ -333,14 +332,14 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
result = await collection.DeleteOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
cancellationToken: cancellationToken
);
}
else
{
result = await collection.DeleteOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
await CreateEntityFilterAsync(entity, true, oldConcurrencyStamp),
cancellationToken
);
}
@ -352,7 +351,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
}
}
public override async Task DeleteManyAsync(
public async override Task DeleteManyAsync(
IEnumerable<TEntity> entities,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -391,10 +390,11 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
BulkWriteResult updateResult;
var replaceRequests = new List<WriteModel<TEntity>>(
softDeletedEntities.Select(entity => new ReplaceOneModel<TEntity>(
CreateEntityFilter(entity.Key, true, entity.Value), entity.Key))
);
var replaceRequests = new List<WriteModel<TEntity>>();
foreach (var softDeletedEntity in softDeletedEntities)
{
replaceRequests.Add(new ReplaceOneModel<TEntity>(await CreateEntityFilterAsync(softDeletedEntity.Key, true, softDeletedEntity.Value), softDeletedEntity.Key));
}
if (dbContext.SessionHandle != null)
{
@ -420,13 +420,13 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
deleteResult = await collection.DeleteManyAsync(
dbContext.SessionHandle,
CreateEntitiesFilter(hardDeletedEntities),
await CreateEntitiesFilterAsync(hardDeletedEntities),
cancellationToken: cancellationToken);
}
else
{
deleteResult = await collection.DeleteManyAsync(
CreateEntitiesFilter(hardDeletedEntities),
await CreateEntitiesFilterAsync(hardDeletedEntities),
cancellationToken: cancellationToken);
}
@ -437,25 +437,25 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
}
}
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
public async override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)).ToListAsync(cancellationToken);
}
public override async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, CancellationToken cancellationToken = default)
public async override Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)).Where(predicate).ToListAsync(cancellationToken);
}
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
public async override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)).LongCountAsync(cancellationToken);
}
public override async Task<List<TEntity>> GetPagedListAsync(
public async override Task<List<TEntity>> GetPagedListAsync(
int skipCount,
int maxResultCount,
string sorting,
@ -471,7 +471,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
.ToListAsync(cancellationToken);
}
public override async Task DeleteAsync(
public async override Task DeleteAsync(
Expression<Func<TEntity, bool>> predicate,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -491,12 +491,12 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
return GetMongoQueryable();
}
public override async Task<IQueryable<TEntity>> GetQueryableAsync()
public async override Task<IQueryable<TEntity>> GetQueryableAsync()
{
return await GetMongoQueryableAsync();
}
public override async Task<TEntity> FindAsync(
public async override Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
@ -544,10 +544,22 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
var dbContext = await GetDbContextAsync(cancellationToken);
var collection = await GetCollectionAsync(cancellationToken);
return ApplyDataFilters(
dbContext.SessionHandle != null
var aggregate = dbContext.SessionHandle != null
? collection.Aggregate(dbContext.SessionHandle)
: collection.Aggregate());
: collection.Aggregate();
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<ISoftDelete>())
{
aggregate = aggregate.Match(e => ((ISoftDelete)e).IsDeleted == false);
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<IMultiTenant>())
{
var tenantId = CurrentTenant.Id;
aggregate = aggregate.Match(e => ((IMultiTenant)e).TenantId == tenantId);
}
return aggregate;
}
protected virtual bool IsHardDeleted(TEntity entity)
@ -561,17 +573,17 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
return hardDeletedEntities.Contains(entity);
}
protected virtual FilterDefinition<TEntity> CreateEntityFilter(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
protected virtual Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
{
throw new NotImplementedException(
$"{nameof(CreateEntityFilter)} is not implemented for MongoDB by default. It should be overriden and implemented by the deriving class!"
$"{nameof(CreateEntityFilterAsync)} is not implemented for MongoDB by default. It should be overriden and implemented by the deriving class!"
);
}
protected virtual FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TEntity> entities, bool withConcurrencyStamp = false)
protected virtual Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TEntity> entities, bool withConcurrencyStamp = false)
{
throw new NotImplementedException(
$"{nameof(CreateEntitiesFilter)} is not implemented for MongoDB by default. It should be overriden and implemented by the deriving class!"
$"{nameof(CreateEntitiesFilterAsync)} is not implemented for MongoDB by default. It should be overriden and implemented by the deriving class!"
);
}
@ -710,22 +722,6 @@ public class MongoDbRepository<TMongoDbContext, TEntity>
{
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 virtual IAggregateFluent<TEntity> ApplyDataFilters(IAggregateFluent<TEntity> aggregate)
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<ISoftDelete>())
{
aggregate = aggregate.Match(e => ((ISoftDelete)e).IsDeleted == false);
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<IMultiTenant>())
{
var tenantId = CurrentTenant.Id;
aggregate = aggregate.Match(e => ((IMultiTenant)e).TenantId == tenantId);
}
return aggregate;
}
}
public class MongoDbRepository<TMongoDbContext, TEntity, TKey>
@ -764,19 +760,7 @@ public class MongoDbRepository<TMongoDbContext, TEntity, TKey>
{
cancellationToken = GetCancellationToken(cancellationToken);
var dbContext = await GetDbContextAsync(cancellationToken);
var collection = dbContext.Collection<TEntity>();
if (dbContext.SessionHandle != null)
{
return await collection
.Find(dbContext.SessionHandle, RepositoryFilterer.CreateEntityFilter(id, true))
.FirstOrDefaultAsync(cancellationToken);
}
return await collection
.Find(RepositoryFilterer.CreateEntityFilter(id, true))
.FirstOrDefaultAsync(cancellationToken);
return await ApplyDataFilters(await GetMongoQueryableAsync(cancellationToken)).Where(x => x.Id.Equals(id)).FirstOrDefaultAsync(cancellationToken);
}
public virtual Task DeleteAsync(
@ -798,13 +782,13 @@ public class MongoDbRepository<TMongoDbContext, TEntity, TKey>
await DeleteManyAsync(entities, autoSave, cancellationToken);
}
protected override FilterDefinition<TEntity> CreateEntityFilter(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
protected async override Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
{
return RepositoryFilterer.CreateEntityFilter(entity, withConcurrencyStamp, concurrencyStamp);
return await RepositoryFilterer.CreateEntityFilterAsync(entity, withConcurrencyStamp, concurrencyStamp);
}
protected override FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TEntity> entities, bool withConcurrencyStamp = false)
protected async override Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TEntity> entities, bool withConcurrencyStamp = false)
{
return RepositoryFilterer.CreateEntitiesFilter(entities, withConcurrencyStamp);
return await RepositoryFilterer.CreateEntitiesFilterAsync(entities, withConcurrencyStamp);
}
}

25
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepositoryFilterer.cs

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
@ -20,7 +21,7 @@ public class MongoDbRepositoryFilterer<TEntity> : IMongoDbRepositoryFilterer<TEn
CurrentTenant = currentTenant;
}
public virtual void AddGlobalFilters(List<FilterDefinition<TEntity>> filters)
public virtual Task AddGlobalFiltersAsync(List<FilterDefinition<TEntity>> filters)
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<ISoftDelete>())
{
@ -32,6 +33,8 @@ public class MongoDbRepositoryFilterer<TEntity> : IMongoDbRepositoryFilterer<TEn
var tenantId = CurrentTenant.Id;
filters.Add(Builders<TEntity>.Filter.Eq(e => ((IMultiTenant)e).TenantId, tenantId));
}
return Task.CompletedTask;
}
}
@ -44,7 +47,7 @@ public class MongoDbRepositoryFilterer<TEntity, TKey> : MongoDbRepositoryFiltere
{
}
public FilterDefinition<TEntity> CreateEntityFilter(TKey id, bool applyFilters = false)
public virtual async Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TKey id, bool applyFilters = false)
{
var filters = new List<FilterDefinition<TEntity>>
{
@ -53,17 +56,17 @@ public class MongoDbRepositoryFilterer<TEntity, TKey> : MongoDbRepositoryFiltere
if (applyFilters)
{
AddGlobalFilters(filters);
await AddGlobalFiltersAsync(filters);
}
return Builders<TEntity>.Filter.And(filters);
}
public FilterDefinition<TEntity> CreateEntityFilter(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
public virtual Task<FilterDefinition<TEntity>> CreateEntityFilterAsync(TEntity entity, bool withConcurrencyStamp = false, string concurrencyStamp = null)
{
if (!withConcurrencyStamp || !(entity is IHasConcurrencyStamp entityWithConcurrencyStamp))
{
return Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id);
return Task.FromResult(Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id));
}
if (concurrencyStamp == null)
@ -71,18 +74,18 @@ public class MongoDbRepositoryFilterer<TEntity, TKey> : MongoDbRepositoryFiltere
concurrencyStamp = entityWithConcurrencyStamp.ConcurrencyStamp;
}
return Builders<TEntity>.Filter.And(
return Task.FromResult<FilterDefinition<TEntity>>(Builders<TEntity>.Filter.And(
Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id),
Builders<TEntity>.Filter.Eq(e => ((IHasConcurrencyStamp)e).ConcurrencyStamp, concurrencyStamp)
);
));
}
public FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TEntity> entities, bool applyFilters = false)
public virtual async Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TEntity> entities, bool applyFilters = false)
{
return CreateEntitiesFilter(entities.Select(s => s.Id), applyFilters);
return await CreateEntitiesFilterAsync(entities.Select(s => s.Id), applyFilters);
}
public FilterDefinition<TEntity> CreateEntitiesFilter(IEnumerable<TKey> ids, bool applyFilters = false)
public virtual async Task<FilterDefinition<TEntity>> CreateEntitiesFilterAsync(IEnumerable<TKey> ids, bool applyFilters = false)
{
var filters = new List<FilterDefinition<TEntity>>()
{
@ -91,7 +94,7 @@ public class MongoDbRepositoryFilterer<TEntity, TKey> : MongoDbRepositoryFiltere
if (applyFilters)
{
AddGlobalFilters(filters);
await AddGlobalFiltersAsync(filters);
}
return Builders<TEntity>.Filter.And(filters);

Loading…
Cancel
Save